尝试使用Comparator按名称排序,忽略大小写,以及先出现空值

我在使用Java 8 Comparator类对项目列表进行排序时遇到问题。

我目前的工作比较如下:

comparator = Comparator.comparing(Person::getName, Comparator.nullsFirst(Comparator.naturalOrder())); 

这有效:它首先按名称对列表进行排序。 但是,我现在试图忽略名称的情况。

我知道我可以编写一个新的getter,它返回全部小写的名称,但我不想采用这种方法,因为我必须为多个属性执行此操作。

在线查看,看起来我应该使用String.CASE_INSENSITIVE_ORDER ,但我看到的唯一示例不包括null排序规范。

我可以这样做:

 comparator = Comparator.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER); 

但是,每当我尝试包含Comparator.nullsFirst我最终都会遇到类型错误,并对如何继续感到困惑。

我试过做一个类似的链

 thenComparing(Comparator.nullsFirst(Comparator.naturalOrder)) 

但这也行不通。

有人可以给我一些建议,告诉我如何将这些链接在一起按名称排序(不区分大小写),然后对空值进行排序。 我似乎对这些类型感到困惑。

您可以在列表中使用两种类型的null 。 您可以使用null Person引用,并且可以使Person具有null名称。

在第一种情况下,您必须将nullsFirst应用于要使用的基准比较器:

 comparator = Comparator.nullsFirst( Comparator.comparing(Person::getName, String.CASE_INSENSITIVE_ORDER)); 

如果您可能nullsFirst名称,则需要确保您的密钥永远不会返回null ,或者您将nullsFirst应用于String.CASE_INSENSITIVE_ORDER 。 第二种选择当然要容易得多:

 comparator = Comparator.comparing( Person::getName, Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER)); 

如果您同时具有两个选项( null引用 null名称),则必须组合两个版本并应用nullsFirst两次:

 comparator = Comparator.nullsFirst( Comparator.comparing( Person::getName, Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER) ) ); 

如果你链接这样的多个比较,外部nullsFirst ,它确保null Person被正确排序,可以应用于整个链:

 comparator = Comparator.nullsFirst( Comparator.comparing( Person::getName, Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER) ).thenComparing(...) );