据我所知,Comparator是一个函数接口,用于比较2个对象和int compare(T o1, T o2),作为接受两个参数的抽象函数.

        List<String> projects=Arrays.asList("abc","def","sss","aaa","bbb");
        projects.stream().sorted((x,y)->y.compareTo(x)).forEach(s->System.out.println(s));
        projects.stream().sorted(Comparator.comparing(s->s)).forEach(s->System.out.println(s));

排序方法将比较器作为参数.所以我能够理解第一个lambda表达式,但我想知道Comparator.comparing(s->s)的用法,也就是说,Comparator.comparing()是用来将单参数lambda表达式转换为双参数lambda表达式的,还是它还有其他用途.

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)

推荐答案

Comparator.comparing()用于将单参数lambda表达式转换为双参数吗?

是的,你可以这样想.

在对事物进行排序时,你应该指定"给定两个事物ab,它们中哪一个更大,还是相等?"使用Comparator<T>.ab就是为什么它有两个lambda参数,你返回一个整数,表示你对这个问题的答案.

然而,一种更方便的方法是指定"给定一个x,你想对x的哪一部分进行by排序?".这就是Comparator.comparingkeyExtractor参数.

比较:

/*
given two people, a and b, the comparison result between a and b is the 
comparison result between a's name and b's name
*/
Comparator<Person> personNameComparator = 
    (a, b) -> a.getName().compareTo(b.getName());

/*
given a person x, compare their name
*/
Comparator<Person> personNameComparator = 
    Comparator.comparing(x -> x.getName()); // or Person::getName

后者显然更加简洁和直观.我们倾向于考虑what件事情进行排序,而不是如何准确地比较两件事情,以及根据比较结果返回的确切数字.

关于comparing人宣言:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)

<T, U extends Comparable<? super U>>部分首先声明了两个泛型类型参数——T是比较器比较的类型(在上面的例子中是Person),U是实际比较的类型(在上面的例子中是String),因此它是extends Comparable.

keyExtractor是您传入的参数,例如x -> x.getName(),它应该回答"当给定T时,您想要比较的U是什么?"的问题.

如果你对? super? extends感到困惑,读What is PECS?.

如果你还没有意识到,comparing的实现基本上可以归结为:

return (a, b) -> keyExtractor.apply(a).compareTo(keyExtractor.apply(b));

Java相关问答推荐

Gmail Javi API批量处理太多请求

如何审查Java dtos中的自定义注释字段?

如何在访问完所有文件后加入所有线程?

Java中后期绑定的替代概念

JDK22执行repackage of goal org. springframework. boot:spring—boot—maven—plugin:3.2.3:repackage failed:unsupported class file major version 66—>

为什么在枚举中分支预测比函数调用快?

流迭代列表<;对象>;上的NoSuchElementException

将带有js文件的 bootstrap 程序导入maven项目时出错

对于亚洲/香港,使用ResolverStyle.STRICT的LocalDate.parse返回意外结果

OpenGL ES 3.0-纹理黑色

匹配一组字符或另一组字符

使SLF4J在Android中登录到Logcat,在测试中登录到控制台(Gradle依赖问题)

如何集成语义发布和BitBucket(Java项目)

在Java泛型中使用通配符时,如何推断类型

在缺少字段时使用Jackson With Options生成Optional.Empty()

我的代码是线程安全的吗?[Java、CAS、转账]

判断重复的两个二维表算法?

在打开搜索结果时,如何让Eclipse打开整个文件?

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

在JPanel上使用GridBagLayout并将JButton放在里面时出现问题