this question has answer here:
- :: (double colon) operator in java 8 13 answers
edit: question here answered. summarize, confused usage of non-static method references. there functional interface , referenced method have different number of parameters.
what answered question comment , accepted answer.
i reading java tutorial stream reduction methods (https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html). there found piece of code thought wrong, made simpler code make sure.
// b.java file import java.util.*; public class b { public static void main(string[] args) { list<integer> zahlen = new linkedlist<integer>(); zahlen.add(1); zahlen.add(2); zahlen.add(3); averager averagecollect = zahlen.stream() .collect(averager::new, averager::addcount, averager::combine); system.out.println(averagecollect.average()); } } // averager.java official java tutorial public class averager { private int total = 0; private int count = 0; public double average() { return count > 0 ? ((double) total)/count : 0; } public void addcount(int i) { total += i; count++;} public void combine(averager other) { total += other.total; count += other.count; } }
the reason thought wouldn't work because of line:
averager averagecollect = zahlen.stream() .collect(averager::new, averager::addcount, averager::combine);
in java documentation stream.collect
(https://docs.oracle.com/javase/8/docs/api/java/util/stream/stream.html#collect-java.util.function.supplier-java.util.function.biconsumer-java.util.function.biconsumer-) says second parameter function matches functional interface biconsumer
required has abstract method 2 arguments. averager.addcount
, averager.combine
have 1 parameter.
i checked lambda expressions:
averager averagecollect = zahlen.stream() .collect(averager::new, (a,b) -> a.addcount(b), (a,b) -> a.combine(b));
this code works , second , third parameter have functions 2 parameters.
why code wrote above work, though functions 1 parameter given? , why there error messages when change both averager.addcount
, averager.combine
have 2 parameters this?
public void addcount(averager one, integer i) public void combine(averager one, averager other)
if following error message:
b.java:12: error: no suitable method found collect(averager::new,averager::addcount,averager::combine) .collect(averager::new, averager::addcount, averager::combine); ^ method stream.collect(supplier,biconsumer,biconsumer) not applicable (cannot infer type-variable(s) r#1 (argument mismatch; invalid method reference cannot find symbol symbol: method addcount(r#1,integer) location: class averager)) method stream.collect(collector) not applicable (cannot infer type-variable(s) r#2,a (actual , formal argument lists differ in length)) r#1,t,r#2,a type-variables: r#1 extends object declared in method collect(supplier,biconsumer,biconsumer) t extends object declared in interface stream r#2 extends object declared in method collect(collector) extends object declared in method collect(collector) 1 error
please me understand.
averager averagecollect = zahlen.stream() .collect(averager::new, averager::addcount, averager::combine);
this fine. equivalent to
averager averagecollect = zahlen.stream() .collect(() -> new averager(), (myaverager, n) -> myaverager.addcount(n), (dst, src) -> dst.combine(src))
remember every nonstatic method has hidden this
parameter. in case (correctly) binding first argument of accumulator
, combiner
callbacks.
it work static methods such as:
public static void addcount(averager a, int i) { a.total += i; a.count++; } public static void combine(averager dst, averager src) { dst.total += src.total; dst.count += src.count; }
which makes clearer happening.
but there no need change code.
Comments
Post a Comment