在 Java 8 流中按属性排序

2022-08-31 15:42:05

哦,那些棘手的Java 8流与lambdas。它们非常强大,但复杂性需要一点点才能将一个人的头包裹起来。

假设我有一个带有属性的类型。假设我有一个与名称(例如登录用户名)关联的用户的地图。让我们进一步假设我有一个比较器的实例来对用户名进行排序(也许有花哨的整理器等)。UserUser.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.INSTANCEUser::getNameUser

奖励:如果我想排序的东西是两层深的,比如?User.getProfile().getUsername()


答案 1

你想要的是比较器#比较

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

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

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

答案 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));

推荐