大家在有关还原(https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html)的Oracle教程中,我们提供了有关如何使用Stream.collect()方法的示例。任务是找到流中的平均值。在该示例中,存在辅助类Averager:class Averager implements IntConsumer{ private int total = 0; private int count = 0; public double average() { return count > 0 ? ((double) total)/count : 0; } public void accept(int i) { total += i; count++; } public void combine(Averager other) { total += other.total; count += other.count; }}然后我们有类似的东西:Averager averageCollect = roster.stream() .filter(p -> p.getGender() == Person.Sex.MALE) .map(Person::getAge) .collect(Averager::new, Averager::accept, Averager::combine).因此,建议我们使用该辅助类的三个方法引用。由于Stream.collect签名为:收集(供应商,BiConsumer累加器,BiConsumer组合器),其中BiConsumer-具有功能方法accept(Object,Object)的功能接口。问题是我们如何才能使用Avereager :: accept(signature void accept(int i)-一个参数,不返回值)代替collect()的第二个参数-该函数是不返回任何值但接受两个参数的函数。如果我们深入研究所有这些库调用,我们可以找到输入lambda的某种转换,从而导致对带有两个参数的accept(a,b)的适当调用,但是编译器最初如何识别它是正确的?我们可以像这样重写collect()调用:... collect(()-> new Averager(),(a,i)-> a.accept(i),Averager :: combine),使用lambda代替方法引用,但我仍然不了解第二个lambda如何具有一个参数,而应该是两个。先感谢您。 最佳答案 我认为混淆在于您可以执行以下操作:Averager avg = new Averager();BiConsumer<Averager, Integer> consumer = Averager::accept;consumer.accept(avg, 17);即使Averager::accept的签名表明它接受一个参数(int i),也可以将其视为接受两个参数的BiConsumer<Averager, Integer>:被调用方(“ this”)和参数()。进一步阅读:The Java™ Tutorials: Method References关于java - Java stream.collect()lambda参数类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27608337/
10-10 12:46