当前位置: 首页 > 面试题库 >

Java 8 Comparator nullsFirst naturalOrder混淆

陶沛
2023-03-14
问题内容

这可能是一个简单的问题,但我想清楚地理解它…

我有这样的代码:

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仅使用一个参数时,将获得“自然顺序”比较器,它 处理空值。(我不确定您是从哪里得到的。)类的“自然顺序”
ComparablecompareTo()方法定义,该方法的用法如下:

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())。但是他们没有,所以您不能那样使用它。



 类似资料:
  • 我一直在摆弄Proguard配置,我想测试只是为了优化 但我仍然会遇到这样的错误: java.lang.IllegalArgumentExc0019:找不到[org/apache/log/log4j/core/jackson/Log4jXmlMoules](有1个已知的超级类)和[org/apache/log/log4j/core/jackson/Log4jJsonMoules](有4个已知的超级

  • Powershell的混淆目前已经使用的越来越多,国内外也有了较多的研究,在今年的BH大会上也有对应的议题,关注点是反混淆,那么里面的一些姿势很值得我们学习,我们提供一些混淆实例,来让大家对于PS的混淆做到一个初步了解,也为防御混淆提供一些思路。 实例 在混淆之前,先看看powershell编码执行的方式。 -EC,-EncodedCommand,-EncodedComman,-EncodedCo

  • 除了传统的面向对象继承方式,还流行一种通过可重用组件创建类的方式,就是联合另一个简单类的代码。 你可能在Scala等语言里对mixins及其特性已经很熟悉了,但它在JavaScript中也是很流行的。 下面的代码演示了如何在TypeScript里使用混入。 后面我们还会解释这段代码是怎么工作的。 // Disposable Mixin class Disposable { isDispos

  • OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。一个有色玻璃窗是一个透明的物体,玻璃有它自己的颜色,但它最终的颜色还包含了玻璃之后所有物体的颜色。这也是混合这一名字的出处,我们混合(Blend)(不同物体的)多

  • 除了传统的面向对象继承方式,还流行一种通过可重用组件创建类的方式,就是联合另一个简单类的代码。 你可能在Scala等语言里对mixins及其特性已经很熟悉了,但它在JavaScript中也是很流行的。 混入示例 下面的代码演示了如何在TypeScript里使用混入。 后面我们还会解释这段代码是怎么工作的。 // Disposable Mixin class Disposable { isD

  • 问题内容: 我正在寻找一个好的Java混淆器。 我已经对以下Java混淆器进行了初步研究:proguard,yguard,retroguard,dasho,alatorari,jshrink,smokescreen,jobfuscate,marvin,jbco,jode,javaguard,jarg,joga,cafebabe,donquixote,mwobfu,bbmug,zelix klass

  • 我对混淆有问题。为了获得更好的想象力: JAVA代码 本机代码 在我想发布一个混淆版本之前,一切都很好。这个类中的Java类(例如)和方法的名称被proGuard重命名为“a”和“a()”(这可能并不总是相同的),但在本机代码中,方法和类的原始名称保持不变,因为它被硬编码为字符串,如下所示: ...有没有办法动态设置方法名?

  • 我正在努力解决JavaFX应用程序的模糊问题。以本项目为基础: Proguard配置文件:-dontoptimized-dontshrink 有人有JavaFX模糊处理的经验吗?