在Java 8流中按属性排序

Gar*_*son 39 java sorting lambda java-8 java-stream

哦,那些棘手的Java 8流与lambdas.它们非常强大,但错综复杂需要一点点围绕它的所有.

假设我有User一个属性类型User.getName().假设我有一个Map<String, User>与名称相关联的用户的地图(例如,登录用户名).让我们进一步说,我有一个比较器的实例UserNameComparator.INSTANCE来排序用户名(可能与花哨的合作者等).

那么如何获取地图中的用户列表,按用户名排序?我可以忽略地图键并执行此操作:

return userMap.values()
    .stream()
    .sorted((u1, u2) -> {
      return UserNameComparator.INSTANCE.compare(u1.getName(), u2.getName());
    })
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但是,我必须提取名称以使用的那一行UserNameComparator.INSTANCE似乎太多的手工工作.有什么方法我可以简单地提供User::getName一些映射函数,只是为了排序,并仍然将User实例返回到收集列表中?

额外奖励:如果我想要排序的东西是两个层次,如User.getProfile().getUsername()

Mis*_*sha 70

你想要的是Comparator#comparing:

userMap.values().stream()
    .sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

对于问题的第二部分,您只需使用

Comparator.comparing(
    u->u.getProfile().getUsername(), 
    UserNameComparator.INSTANCE
)
Run Code Online (Sandbox Code Playgroud)

  • 对于关注者来说,如果不需要特殊的比较器,也可以使用 Comparator.comparing(o -&gt; o.getUsername()) 或 Comparator.comparing(UserNameComparator.INSTANCE) ,如果它可以接受用户而不是名称。FWIW。 (5认同)