【发布时间】:2014-12-08 16:01:27
【问题描述】:
这可能是一个简单的问题,但我想清楚地理解它......
我有这样的代码:
public final class Persona
{
private final int id;
private final String name
public Persona(final int id,final String name)
{
this.id = id;
this.name = name;
}
public int getId(){return id;}
public String getName(){return name;}
@Override
public String toString(){return "Persona{" + "id=" + id + ", name=" + name+'}';}
}
我正在测试这段代码:
import static java.util.Comparator.*;
private void nullsFirstTesting()
{
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));
final List<Persona>persons = Arrays.asList(new Persona(1,"Cristian"),new Persona(2,"Guadalupe"),new Persona(3,"Cristina"),new Persona(4,"Chinga"),new Persona(5,null));
persons
.stream()
.sorted(comparator)
.forEach(System.out::println);
}
这显示了以下结果:
Persona{id=5, name=null}
Persona{id=4, name=Chinga}
Persona{id=1, name=Cristian}
Persona{id=3, name=Cristina}
Persona{id=2, name=Guadalupe}
这些结果对我来说没问题,但我的理解有问题。
当我忽略 new Persona(5,null) 对象并通过比较器时:
final Comparator<Persona>comparator = comparing(Persona::getName);
它就像一个魅力。我的排序是natural order of name property。当我使用name=null 添加对象时出现问题,我只是认为我需要这样的比较器。
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst());
我的想法是错误的:“好的,当name不为null时,它们在natural order of name中排序,就像之前的比较器一样,如果它们是null,它们将是第一个但我的非空名称仍将按自然顺序排序"。
但正确的代码是这样的:
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));
我不明白nullsFirst 的参数。我只是认为natural order of name 会明确地[默认] 甚至处理null 值。
但是文档说:
返回一个认为
null为空值的比较器 小于非空。当两者都是null时,它们被认为是 平等的。如果两者都不为空,则使用指定的Comparator来确定顺序。如果指定的比较器是null, 然后返回的比较器认为所有非空值都是相等的。
这一行:“如果两者都不为空,则使用指定的Comparator 来确定顺序。”
我很困惑何时以及如何明确设置自然顺序或何时推断它们。
【问题讨论】:
-
注意“如果指定的比较器是
null,那么返回的比较器认为所有非空值都是相等的。” 也就是说,你可以做@987654341 @;然而,它只是将空值排序到前面,而不对非空值进行排序。文档实际上解释得很好。 -
@chiperotiz 那么你最终是如何解决的呢?你能先按空值排序,然后按自然顺序排序吗?
-
是的,使用此代码
final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));
标签: java string sorting java-8 comparator