Java 8:按属性对对象列表进行排序,无需自定义比较器

Posted

技术标签:

【中文标题】Java 8:按属性对对象列表进行排序,无需自定义比较器【英文标题】:Java 8: sort list of objects by attribute without custom comparator 【发布时间】:2016-02-02 21:27:09 【问题描述】:

完成这项工作的最简洁的捷径是什么?

class AnObject
    Long  attr;


List<AnObject> list; 

我知道这可以通过AnObject 的自定义比较器来完成。对于这种情况,难道没有现成的东西吗?

有点像这样:

Collections.sort(list, X.attr);

【问题讨论】:

你看过比较器类的javadoc吗?他们添加了一堆方法(顺便说一下你可以直接做list1.sort(..))。 【参考方案1】:

假设你实际上有一个List&lt;AnObject&gt;,你所需要的只是

list.sort(Comparator.comparing(a -> a.attr));

如果你不使用公共字段,而是使用访问器方法来让你的代码更干净,它会变得更干净:

list.sort(Comparator.comparing(AnObject::getAttr));

【讨论】:

如果 attr 为空会怎样? 您能否分享一些链接,我可以在其中阅读有关此内容的详细信息。我想使用多个属性进行排序(例如首先检查 attr1,如果两个 obj 的 attr1 相等,则检查 attr2) @JBNizet AnObject 需要实现 hascode、equals 和 compareTo 吗? 没有。比较器只会对所有对象调用 getAttr() 并比较返回值。 感谢您提供简洁的示例,尽管数据/元组类具有公开的公共字段并没有错。因此,“......如果不使用公共字段则清理”不是一个通用规则。【参考方案2】:

作为@JB Nizet 回答的补充,如果您的 attr 可以为空,

list.sort(Comparator.comparing(AnObject::getAttr));

可能会抛出 NPE。

如果你也想对空值进行排序,可以考虑

    list.sort(Comparator.comparing(a -> a.attr, Comparator.nullsFirst(Comparator.naturalOrder())));

    list.sort(Comparator.comparing(a -> a.attr, Comparator.nullsLast(Comparator.naturalOrder())));

这会将空值放在第一位或最后。

【讨论】:

【参考方案3】:

对于 JB Nizet 和 Alex 的上述回答,一个空安全选项是执行以下操作:

list.sort(Comparator.comparing(AnObject::getAttr, Comparator.nullsFirst(Comparator.naturalOrder())));

list.sort(Comparator.comparing(AnObject::getAttr, Comparator.nullsLast(Comparator.naturalOrder())));

【讨论】:

以上是关于Java 8:按属性对对象列表进行排序,无需自定义比较器的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 进阶手册(XX):使用 Comparator 对列表进行排序

Java 8 进阶手册(XX):使用 Comparator 对列表进行排序

在Objective-C中按一个属性对自定义对象的NSSet进行排序

java 如何对对象进行排序

java按可指定属性对对象列表进行排序

C# LINQ 组按属性集合,然后按列表定义的显式顺序对每个组进行排序[重复]