Java 8 流的 .min() 和 .max():为什么要编译? [英] Java 8 stream's .min() and .max(): why does this compile?

查看:39
本文介绍了Java 8 流的 .min() 和 .max():为什么要编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这个问题来自一个死链接,这是一个以前的 SO 问题,但这里是...

Note: this question originates from a dead link which was a previous SO question, but here goes...

请参阅此代码(注意:我确实知道此代码不会工作"并且应该使用 Integer::compare —— 我刚刚从链接的问题中提取了它):

See this code (note: I do know that this code won't "work" and that Integer::compare should be used -- I just extracted it from the linked question):

final ArrayList <Integer> list 
    = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());

System.out.println(list.stream().max(Integer::max).get());
System.out.println(list.stream().min(Integer::min).get());

根据.min().max(),两者的参数应该是一个Comparator.然而这里的方法引用是 Integer 的静态方法 类.

According to the javadoc of .min() and .max(), the argument of both should be a Comparator. Yet here the method references are to static methods of the Integer class.

那么,为什么要编译?

推荐答案

让我解释一下这里发生的事情,因为它并不明显!

Let me explain what is happening here, because it isn't obvious!

首先,Stream.max() 接受 Comparator 以便可以将流中的项目相互比较以找到最小值或最大值,以某种最佳顺序太担心了.

First, Stream.max() accepts an instance of Comparator so that items in the stream can be compared against each other to find the minimum or maximum, in some optimal order that you don't need to worry too much about.

所以问题当然是,为什么 Integer::max 接受了吗?毕竟不是比较器!

So the question is, of course, why is Integer::max accepted? After all it's not a comparator!

答案在于新的 lambda 功能在 Java 8 中的工作方式.它依赖于一个非正式地称为单一抽象方法"接口或SAM"接口的概念.这个想法是任何具有一个抽象方法的接口都可以由任何 lambda - 或方法引用 - 自动实现,其方法签名与接口上的一个方法匹配.所以检查 Comparator界面(简单版):

The answer is in the way that the new lambda functionality works in Java 8. It relies on a concept which is informally known as "single abstract method" interfaces, or "SAM" interfaces. The idea is that any interface with one abstract method can be automatically implemented by any lambda - or method reference - whose method signature is a match for the one method on the interface. So examining the Comparator interface (simple version):

public Comparator<T> {
    T compare(T o1, T o2);
}

如果一个方法正在寻找一个Comparator,那么它本质上就是在寻找这个签名:

If a method is looking for a Comparator<Integer>, then it's essentially looking for this signature:

int xxx(Integer o1, Integer o2);

我使用xxx"因为方法名称不用于匹配目的.

因此,Integer.min(int a, int b)Integer.max(int a, int b) 都足够接近,自动装箱将允许它在方法上下文中显示为 Comparator.

Therefore, both Integer.min(int a, int b) and Integer.max(int a, int b) are close enough that autoboxing will allow this to appear as a Comparator<Integer> in a method context.

这篇关于Java 8 流的 .min() 和 .max():为什么要编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆