来自嵌套 POJO 的比较器
Comparator from nested POJO
我想按 属性 也是 POJO 对我的 POJO 列表进行排序。比较器应将 null
值移动到列表的末尾。 null
已经处于第二个 POJO 级别。
假设以下 POJO:
public class Foo {
private Bar bar;
private boolean set;
// getter and setter omitted
}
public class Bar {
private String name1;
private String name2;
// getter and setter omitted
}
现在我有一个 List<Foo>
应该按 Bar#name1
排序。
到目前为止我有以下代码:
Collections.sort(fullList, Comparator.comparing(Foo::getBar::getName1,
Comparator.nullsLast(Comparator.naturalOrder())));
遗憾的是,这不起作用,因为无法链接 ::
运算符。所以我更新了 Bar
class 来实现 Comparator<Bar>
public class Bar implements Comparator<Bar> {
private String name1;
private String name2;
// getter and setter omitted
@Override
public int compare(Bar o1, Bar o2) {
return o1.getName1().compareTo(o2.getName1());
}
}
并将我的排序代码更改为:
Collections.sort(fullList, Comparator.comparing(Foo::getBar,
Comparator.nullsLast(Comparator.naturalOrder())));
但这给了我编译错误:
The method comparing(Function, Comparator) in the type Comparator is not applicable for the arguments (Foo::getBar, Comparator>>)
以及
The type Foo does not define getBar(T) that is applicable here
我在第二部分做错了什么?我该如何解决?
编辑:
我刚刚意识到缺少一个关键部分。
在列表中,Foo
永远不会是 null
,但 Bar
可能是 null
。在 Bar
为 null
的情况下,Foo
应移至列表末尾。
您可以在第一种方法中简单地使用 lambda:
fooList.sort(Comparator.comparing(f -> f.getBar().getName1(),
Comparator.nullsLast(Comparator.naturalOrder())))
当您希望使 Bar
具有可比性时,您应该:
@Getter
class Bar implements Comparable<Bar> {
private String name1;
private String name2;
@Override
public int compareTo(Bar o) {
return name1.compareTo(o.getName1());
}
}
然后用
跟进
fooList.sort(Comparator.comparing(Foo::getBar,
Comparator.nullsLast(Comparator.naturalOrder())));
对于Comparator<T>
,签名是:
static <T,U extends Comparable<? super U>> Comparator<T>
comparing(Function<? super T,? extends U> keyExtractor)
所以Foo::getBar
的结果必须实现Comparable
。 Bar
实现 Comparator
,而不是 Comparable
。
Oracle 关于 comparing 方法的文档详细阐述了(强调我的):
Accepts a function that extracts a Comparable sort key from a type T..
我想按 属性 也是 POJO 对我的 POJO 列表进行排序。比较器应将 null
值移动到列表的末尾。 null
已经处于第二个 POJO 级别。
假设以下 POJO:
public class Foo {
private Bar bar;
private boolean set;
// getter and setter omitted
}
public class Bar {
private String name1;
private String name2;
// getter and setter omitted
}
现在我有一个 List<Foo>
应该按 Bar#name1
排序。
到目前为止我有以下代码:
Collections.sort(fullList, Comparator.comparing(Foo::getBar::getName1,
Comparator.nullsLast(Comparator.naturalOrder())));
遗憾的是,这不起作用,因为无法链接 ::
运算符。所以我更新了 Bar
class 来实现 Comparator<Bar>
public class Bar implements Comparator<Bar> {
private String name1;
private String name2;
// getter and setter omitted
@Override
public int compare(Bar o1, Bar o2) {
return o1.getName1().compareTo(o2.getName1());
}
}
并将我的排序代码更改为:
Collections.sort(fullList, Comparator.comparing(Foo::getBar,
Comparator.nullsLast(Comparator.naturalOrder())));
但这给了我编译错误:
The method comparing(Function, Comparator) in the type Comparator is not applicable for the arguments (Foo::getBar, Comparator>>)
以及
The type Foo does not define getBar(T) that is applicable here
我在第二部分做错了什么?我该如何解决?
编辑:
我刚刚意识到缺少一个关键部分。
在列表中,Foo
永远不会是 null
,但 Bar
可能是 null
。在 Bar
为 null
的情况下,Foo
应移至列表末尾。
您可以在第一种方法中简单地使用 lambda:
fooList.sort(Comparator.comparing(f -> f.getBar().getName1(),
Comparator.nullsLast(Comparator.naturalOrder())))
当您希望使 Bar
具有可比性时,您应该:
@Getter
class Bar implements Comparable<Bar> {
private String name1;
private String name2;
@Override
public int compareTo(Bar o) {
return name1.compareTo(o.getName1());
}
}
然后用
跟进fooList.sort(Comparator.comparing(Foo::getBar,
Comparator.nullsLast(Comparator.naturalOrder())));
对于Comparator<T>
,签名是:
static <T,U extends Comparable<? super U>> Comparator<T>
comparing(Function<? super T,? extends U> keyExtractor)
所以Foo::getBar
的结果必须实现Comparable
。 Bar
实现 Comparator
,而不是 Comparable
。
Oracle 关于 comparing 方法的文档详细阐述了(强调我的):
Accepts a function that extracts a Comparable sort key from a type T..