问题描述
class dish {
public int getCalories() {
return calories;
}
public static final List<dish> menu = Arrays.asList(
new dish("pork",false,800,dish.Type.MEAT),new dish("beef",700,new dish("chicken",400,new dish("french fries",true,530,dish.Type.OTHER),new dish("rice",350,new dish("season fruit",120,new dish("pizza",550,new dish("prawns",dish.Type.FISH),new dish("salmon",450,dish.Type.FISH)
);
}
当dish::getCalories
需要summingInt
时,以下ToIntFunction
方法引用如何有效?我问是因为getcalories
的签名与applyAsInt
的{{1}}抽象方法的签名不匹配
ToIntFunction
解决方法
我问是因为
getCalories
的签名与applyAsInt
的{{1}}抽象方法的签名不匹配。
实际上,它确实匹配。
ToIntFunction
是功能性接口,因为它具有注释ToIntFunction<T>
。这意味着@FunctionalInterface
的签名与提供从applyAsInt
映射到<T>
的方法的任何class 1 ,方法引用或lambda匹配。
在这种情况下,int
通过调用Dish::getCalories
实例的Dish
方法将int
映射到Dish
:
- 映射的来源是
getCalories()
的实例 - 映射的结果是在实例 2 上调用
Dish
的结果。
(注意:这是一个直观的说明。有关技术说明,请参阅JLS的相关部分。)
1-在提供类实例的情况下,类API中只能有一种方法满足功能接口的要求。因此,假设假设getCalories()
用Dish
批注声明,则它无法公开两个不带参数并返回@ToIntFunction<Dish>
的方法。
2-应用常规方法覆盖规则。如果实际对象是int
子类型的实例,并且它覆盖了Dish
,则映射将调用 that 方法,而不是覆盖的方法。
对于任何想知道它为什么起作用的人。之所以起作用,是因为this
是对象的每种方法的隐式第一个参数。因此,Dish::getCalories
的签名与applyAsInt
的{{1}}相同。如果我错了,请纠正我。
嗯,很好,它在这里有效!我不确定这里是否还有隐藏的东西。
import java.util.List; import static java.util.stream.Collectors.summingInt; import java.util.Arrays; class Dish { public int getCalories() { return calories; } public static final List menu = Arrays.asList( new Dish("pork",false,800,Dish.Type.MEAT),new Dish("beef",700,new Dish("chicken",400,new Dish("french fries",true,530,Dish.Type.OTHER),new Dish("rice",350,new Dish("season fruit",120,new Dish("pizza",550,new Dish("prawns",Dish.Type.FISH),new Dish("salmon",450,Dish.Type.FISH) ); public static void main(String[] args) { int totalCalories = menu.stream().collect(summingInt(Dish::getCalories)); System.out.println(totalCalories); } String name; int calories; Dish.Type type; public Dish(String name,boolean b,int calories,Dish.Type type) { super(); this.name = name; this.calories = calories; this.type = type; } enum Type { MEAT,FISH,OTHER } }