使用Comparator接口和Java 8流进行排序

23

Parent是一个被Child继承的类,Child又被GrandChild继承。每个类都包含子类的列表(即Parent包含Child的列表,Child包含GrandChild的列表)。每个类都包含50个属性(attrib1-atrib50)。 getChildList()返回类型为Child对象的arrayList,getGrandChildList()返回类型为GrandChild对象的arrayList。

让resultSet成为Parent的列表。

List<Parent> resultSet

现在我想根据一些属性对列表进行排序。例如,如果我想根据两个父属性(比如 Attribute 1 和 attribute 2)对 resultSet 进行排序,我使用以下代码。

Comparator<Parent> byFirst = (e1, e2) -> e2.getAttrib1().compareTo(e1.getAttrib1());
Comparator<Parent> bySecond = (e1, e2) -> e1.getAttrib2().compareTo(e2.getAttrib2());

Comparator<Parent> byThird = byFirst.thenComparing(bySecond);


List<Parent> sortedList = resultSet.stream().sorted(byThird).collect(Collectors.toList());

现在我想根据Child类的属性1和GrandChild类的属性1对parentlist进行排序。我该如何排序。


1
如果每个“Parent”都有许多“Child”,您如何按“Child”的属性对“Parent”列表进行排序? 您将使用列表中的哪个“Child”来获取要比较的属性? - Misha
通过 getChildList() 方法,我可以访问子元素并选择一个子元素属性。 - Manu Joy
1
那么,如果一个父级元素有10个子元素,每个子元素的attr1取值都不同,你会用哪一个? - Misha
1个回答

33

使用 Comparator.comparing 来创建比较器。只需确定您要比较的内容即可。它将看起来类似于这样,不过您可以编写任何逻辑来提取要比较的值:

使用 Comparator.comparing 来创建比较器。只需确定您要比较的内容即可。它将看起来类似于这样,不过您可以编写任何逻辑来提取要比较的值:

Comparator<Parent> byAttr1ofFirstChild = Comparator.comparing(
    parent -> parent.getChildren().get(0).getAttr1()
);

Comparator<Parent> byAttr1ofFirstGrandChild = Comparator.comparing(
    parent -> parent.getChildren().get(0).getGrandChildren().get(0).getAttr1()
);


List<Parent> sortedList = parents.stream()
    .sorted(byAttr1ofFirstChild.thenComparing(byAttr1ofFirstGrandChild))
    .collect(toList());

Comparator.comparing也可以使用静态导入,从而使您问题中的示例更加简洁:

Comparator<Parent> byFirst = comparing(Parent::getAttrib1, reverseOrder());
Comparator<Parent> bySecond = comparing(Parent::getAttrib2);

reverseOrder():我无法在我的IDE中识别此方法。 - Manu Joy
2
它是Comparator.reverseOrder(),但使用静态导入使代码更加简洁。 - Misha
1
或者您可以执行 comparing(Parent::getAttrib1).reversed(); - Alexis C.
1
@AlexisC。遗憾的是,comparing(...).reversed() 只适用于以方法引用形式存在的键提取器。如果您尝试执行 comparing(parent->parent.getAttrib1()).reversed(),编译器将不会接受它,除非在 parent 变量上进行类型提示。另一方面,comparing(parent->parent.getAttrb1(), reverseOrder()) 将正常工作。 - Misha
1
@Misha 是的,我知道。我期望未来会有所改进,使这种构造能够正常工作 :-) - Alexis C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接