这可能是一个简单的问题,但我想清楚地理解它...
我有这样的代码:
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());
我的想法是错误的:“好吧,当名称为非空时,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
则使用指定的命令来确定顺序。”
我对何时以及如何显式设置自然顺序或何时推断自然顺序感到困惑。
当您comparing
仅使用一个参数时,将获得“自然顺序”比较器,它不处理空值。(我不确定您是从哪里得到的。)类的“自然顺序” Comparable
是由compareTo()
方法定义的,该方法的用法如下:
obj1.compareTo(obj2)
显然,如果obj1
为null,则此方法无效。对于String
,如果obj2
为null ,也会抛出异常。
该naturalOrder()
方法返回Comparator
比较两个对象的。在javadoc中明确地说,这种比较引发NullPointerException
比较空的时候。
该nullsFirst()
方法(和nullsLast()
类似地)基本上将a Comparator
转换为new Comparator
。您放入了一个比较器,如果它试图比较null,它可能会引发异常,并且它吐出一个新的比较器,该比较器的工作方式相同,不同之处在于它允许使用null参数。所以这就是为什么需要一个参数- nullsFirst
因为它会在现有比较器之上构建一个新的比较器,并告诉它现有的比较器是什么。
那么,如果省略该参数,为什么不给您自然顺序呢?因为他们没有那样定义。nullsFirst
在javadoc中定义为采用参数:
static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)
我认为,如果设计人员愿意,他们可以添加不带参数的重载:
static <T> Comparator<T> nullsFirst() // note: not legal
与使用相同nullsFirst(naturalOrder())
。但是他们没有,所以您不能那样使用它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句