【问题标题】:Sorting by property in Java 8 stream在 Java 8 流中按属性排序
【发布时间】:2014-12-21 12:13:58
【问题描述】:

哦,那些带有 lambda 的棘手 Java 8 流。它们非常强大,但错综复杂的东西需要一点时间才能将其全部包含在标题中。

假设我有一个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());

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

奖励:如果我想要排序的内容有两个层次,例如User.getProfile().getUsername(),该怎么办?

【问题讨论】:

    标签: java sorting lambda java-8 java-stream


    【解决方案1】:

    你要的是Comparator#comparing:

    userMap.values().stream()
        .sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE))
        .collect(Collectors.toList());
    

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

    Comparator.comparing(
        u->u.getProfile().getUsername(), 
        UserNameComparator.INSTANCE
    )
    

    【讨论】:

    • 哇,我的大脑几乎要痛了,但这正是我想要的,奖金和一切!还有超快速的反应。谢谢!
    • 对于关注者,如果你不需要特殊的比较器,你也可以使用Comparator.comparing(o -> o.getUsername())Comparator.comparing(UserNameComparator.INSTANCE)如果它可以接受用户而不是名字。 FWIW。
    【解决方案2】:

    为了在第二级进行比较,您可以这样进行: 对于对象

    public class ArticleChannel {
    
        private Long id;
        private String label;
        private ArticleBusiness business;
    }
    
    public class ArticleBusiness {
        private Long id;
        private String name;
    }
    
    articleChannelList.sort(Comparator.comparing((ArticleChannel articleChannel) -> **articleChannel.getBusiness().getName()**).thenComparing(ArticleChannel::getLabel));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多