【问题标题】:Attempting to use Comparator to sort by name, ignore case, as well as nulls first尝试使用 Comparator 按名称排序,忽略大小写,以及首先使用空值
【发布时间】:2017-10-06 16:24:54
【问题描述】:

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

我目前的工作比较器如下:

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

这很有效:它首先使用空值按名称对列表进行排序。但是,我现在尝试忽略名称的大小写。

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

在网上看,我应该使用String.CASE_INSENSITIVE_ORDER,但我看到的唯一示例不包括空排序规范。

我可以这样做:

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

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

我试过做一个类似于

的链
thenComparing(Comparator.nullsFirst(Comparator.naturalOrder))

但这也行不通。

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

【问题讨论】:

  • 您可以非常轻松地编写自己的Comparator,而不是使用罐头。罐装的适用于最常见的用例,显然不适用于您。
  • 你不能像使用 Comparator.naturalOrder() 一样将 String.CASE_INSENSITIVE_ORDER 包裹在 Comparator.nullsFirst(...) 中吗?
  • 如果您正在制作自定义比较器 BTW,为什么要使用 naturalOrder
  • @MadPhysicist 我不想制作自己的比较器,因为我需要对许多不同对象的许多不同属性进行相同的排序。我宁愿有一行代码,我可以改变每个的属性。
  • @Bubletan 看起来成功了!谢谢

标签: java comparator


【解决方案1】:

您的列表中有两种类型的nulls。您可以拥有 null Person 引用,并且您可以拥有 Persons 和 null 名称。

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

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

如果您有null 名称的可能性,您需要确保您的密钥永远不会返回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)
        )
);

如果您像这样链接多个比较,则可以将确保 null Persons 正确排序的外部 nullsFirst 应用于整个链:

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

【讨论】:

  • 非常感谢!
  • @Aweava。没问题。随着它们向所有内容添加新功能和越来越多的泛型,该语言变得越来越模糊。我感谢您为此付出的努力并理解您的困惑。年纪大了,有时可以学习 java 1.4 版真是太好了:)
  • 经过一些测试,这些方法似乎不起作用。在我没有得到 NPE 之前,尝试对任何具有空值的数据进行排序时,我得到了 NPE
  • 只是为了澄清:最初我的代码在排序时有效,但它区分大小写。使用这些方法,当集合中有 nulll 属性时,它会抛出 NPE
  • @Aweava。我会调查并修复。
猜你喜欢
  • 2019-10-18
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多