Attempting to use Comparator to sort by name, ignore case, as well as nulls first

不想你离开。 提交于 2019-12-07 08:35:24

问题


I am having issues using the Java 8 Comparator class to sort a list of items.

My current working comparator is below:

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

This works: it orders the list by name with the null values first. However, I am now attempting to ignore case of the names.

I know that I can write a new getter that returns the name all lowercase, but I do not want to go with this approach as I have to do this for multiple attributes.

Looking online, it looks like I should be using String.CASE_INSENSITIVE_ORDER, but the only examples I see do not include the null ordering specification.

I can do something like this:

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

However, whenever I try to include the Comparator.nullsFirst I end up getting type errors, and am confused on how to continue.

I've tried doing a chain similar to

thenComparing(Comparator.nullsFirst(Comparator.naturalOrder))

but that also doesn't work.

Could someone lend me some advice on how I can chain these together to sort by name (not case sensitive) and then order the nulls. I seem to be confusing myself with the types.


回答1:


There are two types of nulls you can have in your list. You can have null Person references, and you can have Persons with null names.

In the first case, you have to apply nullsFirst to the base comparator you want to use:

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

If you have the possibility of null names, you need to make sure that your key never returns a null, or that you apply nullsFirst to String.CASE_INSENSITIVE_ORDER. The second option is of course much easier:

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

If you have both options (null references and null names), you will have to combine both versions and apply nullsFirst twice:

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

If you are chaining multiple comparisons like this, the outer nullsFirst, which ensures that null Persons get sorted properly, can be applied to the entire chain:

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


来源:https://stackoverflow.com/questions/46610076/attempting-to-use-comparator-to-sort-by-name-ignore-case-as-well-as-nulls-firs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!