Comparator for Optional ,带有键提取器,例如java.util.Comparator.comparing

问题描述 投票:1回答:1

考虑下面的示例,我们将根据他们的姓氏对他们进行排序:

public class ComparatorsExample {

    public static class Person {
        private String lastName;

        public Person(String lastName) {
            this.lastName = lastName;
        }

        public String getLastName() {
            return lastName;
        }

        @Override
        public String toString() {
            return "Person: " + lastName;
        }
    }

    public static void main(String[] args) {
        Person p1 = new Person("Jackson");
        Person p2 = new Person("Stackoverflowed");
        Person p3 = new Person(null);
        List<Person> persons = Arrays.asList(p3, p2, p1);
        persons.sort(Comparator.comparing(Person::getLastName));
    }
}

现在,让我们假设getLastName返回一个可选值:

public Optional<String> getLastName() {
    return Optional.ofNullable(lastName);
}

显然persons.sort(Comparator.comparing(Person::getLastName));将不会编译,因为OptionalgetLastName返回的类型)不可比较。但是,它持有的价值是。

[第一个Google搜索将我们指向this answer。基于此答案,我们可以通过执行以下操作对人员进行排序:

List<Person> persons = Arrays.asList(p3, p2, p1);
OptionalComparator<String> absentLastString = absentLastComparator();
persons.sort((r1, r2) -> absentLastString.compare(r1.getLastName(), r2.getLastName()));

我的问题是,是否有可能像Comparator.comparing一样使用函数(键提取器)进行这种排序?

我的意思是((不在乎值的开头或结尾):

persons.sort(OptionalComparator.comparing(Person::getLastName));

[如果我们查看Comparator.comparing,我们将看到以下代码:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor) {
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable) (c1, c2) -> {
        return keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    };
}

我尝试了多种方法使其返回OptionalComparator而不是简单的Comparator,但是我尝试并认为对我有意义的所有内容都无法编译。 甚至有可能实现这样的目标吗?我猜想类型安全性无法实现,因为即使Oracle的comparing也会引发类型安全性警告。

我使用Java 8。

java generics lambda collections comparable
1个回答
0
投票

您可以使用Comparator#comparing(Function,Comparator)

[接受从类型Comparator#comparing(Function,Comparator)中提取排序键,然后返回T的函数,该功能使用指定的Comparator<T>与该排序键进行比较。

这是一个基于您的问题代码的示例:

Comparator

基本上,这是使用嵌套的键提取器来最终比较代表姓氏的persons.sort(comparing(Person::getLastName, comparing(Optional::get)); 对象。请注意,如果其中一个String为空,则将引发NoSuchElementException

© www.soinside.com 2019 - 2024. All rights reserved.