哦,那些棘手的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());
但是,我必须提取名称以使用UserNameComparator.INSTANCE
的那一行似乎是太多的手工工作。有没有什么方法可以简单地提供User::getName
作为一些映射函数,仅用于排序,并且仍然将User
实例返回到收集列表中?
奖励:如果我想要排序的东西有两个级别,例如User.getProfile().getUsername()
,该怎么办?
答案 0 :(得分:66)
你想要的是Comparator#comparing
:
userMap.values().stream()
.sorted(Comparator.comparing(User::getName, UserNameComparator.INSTANCE))
.collect(Collectors.toList());
对于问题的第二部分,您只需使用
Comparator.comparing(
u->u.getProfile().getUsername(),
UserNameComparator.INSTANCE
)
答案 1 :(得分:0)
为了在第二级进行比较,您可以这样进行: 为对象
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));