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