去查了一圈资料,大概是弄懂了原因,我尝试说明一下:
strs.stream().map(Long::valueOf).collect(LinkedHashSet::new, HashSet::add, HashSet::addAll);
不使用 Method Reference 的形式可以写成:
strs.stream().collect(LinkedHashSet::new, (set, element) -> set.add(element), (set1, set2) -> set1.addAll(set2));
这样看,(set, element) -> set.add(element) 是不是符合 BiConsumer 的 void accept(T t, U u); 方法定义了呢?
而为什么(set, element) -> set.add(element) 可以写成 HashSet::add 的形式:
不管是 add 还是 addAll 都是实例方法,当实例方法被用做 Method Reference 的时候,receiver 会将 this 作为第一个参数传入,比如 Oracle 官方 Tutorial (
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html )中的这个例子:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
String::compareToIgnoreCase 等价于 (a, b) -> a.compareToIgnoreCase(b); 只不过是写成 String::compareToIgnoreCase 这种形式时,编译器会自动帮你处理改写。
参考:
https://moandjiezana.com/blog/2014/understanding-method-references/http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html