在 Java 8 流中按属性排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26568555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:49:56  来源:igfitidea点击:

Sorting by property in Java 8 stream

javasortinglambdajava-8java-stream

提问by Garret Wilson

Oh, those tricky Java 8 streams with lambdas. They are very powerful, yet the intricacies take a bit to wrap one's header around it all.

哦,那些带有 lambda 表达式的棘手 Java 8 流。它们非常强大,但复杂的东西需要一点时间才能将一个人的标题包裹起来。

Let's say I have a Usertype with a property User.getName(). Let's say I have a map of those users Map<String, User>associated with names (login usernames, for example). Let's further say I have an instance of a comparator UserNameComparator.INSTANCEto sort usernames (perhaps with fancy collators and such).

假设我有一个User带有属性的类型User.getName()。假设我有一张Map<String, User>与姓名(例如,登录用户名)相关联的用户的地图。让我们进一步说我有一个比较器的实例UserNameComparator.INSTANCE来对用户名进行排序(也许有花哨的校对者等)。

So how do I get a list of the users in the map, sorted by username? I can ignore the map keys and do this:

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

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

But that line where I have to extract the name to use the UserNameComparator.INSTANCEseems like too much manual work. Is there any way I can simply supply User::getNameas some mapping function, just for the sorting, and still get the Userinstances back in the collected list?

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

Bonus: What if the thing I wanted to sort on were two levels deep, such as User.getProfile().getUsername()?

奖励:如果我想排序的东西有两个级别深,例如User.getProfile().getUsername()?

采纳答案by Misha

What you want is Comparator#comparing:

你想要的是Comparator#comparing

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

For the second part of your question, you would just use

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

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