Java 8 Comparator nullsFirst naturalOrder困惑 [英] Java 8 Comparator nullsFirst naturalOrder confused

查看:3828
本文介绍了Java 8 Comparator nullsFirst naturalOrder困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

this may be a simple question but I would like to understand it clearly...

我有这样的代码:

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}

这些结果对我来说没问题,但我理解有问题。

These results are OK with me but I have a problem understanding.

当我忽略新的Persona( 5,null)对象和我传递比较器:

When I ignore the new Persona(5,null) object and I pass the comparator:

final Comparator<Persona>comparator = comparing(Persona::getName);

它就像一个魅力。我的排序是 name属性的自然顺序。当我用 name = null 添加对象时出现问题,我只是觉得我需要这样的比较器。

It works like a charm. My sorting is by natural order of name property. The problem arises when I add the object with name=null, I just thought I would need my comparator like this.

final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst());

我的想法是错误:好的,当名字非空时,它们按自然顺序排序,就像上一个比较器一样,如果它们是 null ,它们将是第一个但我的非空名称仍将按自然顺序排序

My thought was erroneous: "OK, when name is non-null, they are sorted in natural order of name, just like the previous comparator, and if they are null they will be first but my non-null names will still be sorted in natural order".

但正确的代码是:

final Comparator<Persona>comparator = comparing(Persona::getName,nullsFirst(naturalOrder()));

我不明白参数 nullsFirst 。我只是认为名称的自然顺序将显式[默认]甚至处理 null 值。

I don't understand the parameter to nullsFirst. I just thought the natural order of name would explicitly [default] even handle null values.

但文档说:


返回一个考虑的无效比较器null
小于非null。当两者都是 null 时,它们被视为
等于。如果两者都是非null,则使用
来指定 Comparator 来确定订单。如果指定的比较器是 null
则返回的比较器认为所有非空值都相等。

Returns a null-friendly comparator that considers null to be less than non-null. When both are null, they are considered equal. If both are non-null, the specified Comparator is used to determine the order. If the specified comparator is null, then the returned comparator considers all non-null values to be equal.

这一行:如果两者都是非null,则使用指定的 Comparator 来确定订单。

This line: "If both are non-null, the specified Comparator is used to determine the order."

我很困惑何时以及如何明确设定自然顺序或推断它们。

I am confused when and how the natural order should be explicitly set or when they are inferred.

推荐答案

使用比较只有一个参数时得到的自然顺序比较器,处理空值。 (我不确定你的想法是什么。) Comparable 类的自然顺序由 compareTo定义( )方法,使用如下:

The "natural order" comparator, which is what you get when you use comparing with only one parameter, does not handle nulls. (I'm not sure where you got the idea that it did.) The "natural order" of a Comparable class is defined by the compareTo() method, which is used like this:

obj1.compareTo(obj2)

如果 obj1 为空,显然这不起作用;对于 String ,它也会抛出的异常.obj2 为空。

Obviously this won't work if obj1 is null; for String, it will also throw an exception of obj2 is null.

naturalOrder()方法返回一个比较两个对象的比较器 javadoc 明确表示此比较器抛出 NullPointerException 比较null。

The naturalOrder() method returns a Comparator that compares two objects. The javadoc explicitly says that this comparator throws NullPointerException when comparing null.

nullsFirst()方法(并且 nullsLast()类似地)基本上将比较器转换为新的比较器。你输入一个比较器,如果它试图比较null,它可能抛出一个异常,它会吐出一个新的比较器,它的工作方式相同,只是它允许空参数。这就是为什么你需要一个参数 nullsFirst - 因为它在现有的比较器之上构建一个新的比较器,你告诉它现有的比较器是什么。

The nullsFirst() method (and nullsLast() similarly) basically transforms a Comparator to a new Comparator. You put in a comparator that may throw an exception if it tries to compare null, and it spits out a new comparator that works the same way except that it allows null arguments. So that's why you need a parameter to nullsFirst--because it builds a new comparator on top of an existing comparator, and you tell it what the existing comparator is.

那么,如果省略参数,为什么不给你自然顺序呢?因为他们没有这样定义。 nullsFirst javadoc 获取参数:

So why doesn't it give you the natural order if you leave out the parameter? Because they didn't define it that way. nullsFirst is defined in the javadoc to take a parameter:

static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator)

我认为如果设计师想要,他们可以添加了一个不带参数的重载:

I think that if the designers wanted to, they could have added an overload that takes no parameters:

static <T> Comparator<T> nullsFirst()  // note: not legal

与使用 nullsFirst(naturalOrder())。但他们没有,所以你不能那样使用它。

that would be the same as using nullsFirst(naturalOrder()). But they didn't, so you can't use it like that.

这篇关于Java 8 Comparator nullsFirst naturalOrder困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆