Java 8方法引用背后的原理

3
我的问题是Lambda表达式和方法引用都与函数接口有关,它们只是提供了其实现。现在当我编写以下代码时:
class Apple{
private int weight;
private String color;

public String getColor() {
    return color;
}

public void setColor(String color) {
    this.color = color;
}

public int getWeight() {
    return weight;
}

public void setWeight(int weight) {
    this.weight = weight;
}}

如果我写:

            Function<Apple, Integer> getWeight = Apple::getWeight;

或者

        appleList.stream().map(Apple::getColor).collect(toList());

我的getter方法为什么不需要任何参数就能正常工作呢?这是因为它符合函数式接口的规范。
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);}

它需要一个参数并返回一些内容,当getter像这样时,它应该实际工作:

public int getWeight(Apple a) {
    return a.weight;
}

我有点困惑,提前感谢。

2个回答

4

这样的 Function<Apple, Integer> 不应与 Apple 的实例混淆。

还记得学校里的函数吗?
你需要从定义域(这里是 Apple 中的一个苹果)中取出一个元素,并将其匹配到对应的值域(这里是 Integer 中的一个整数)。Function 本身并没有分配给任何特定的苹果。

你可以这样使用它:

List<Apple> apples = new ArrayList<Apple>();
apples.add(new Apple(120, "red"));
apples.add(new Apple(150, "green"));
apples.add(new Apple(150, "yellow"));
List<String> colors = apples.stream()
                            .map(Apple::getColor)
                            .collect(Collectors.toList());
System.out.println(colors);

Apple::getColor 等同于一个返回每个苹果颜色的 Function<Apple, String>

Function<Apple, Integer> getColor = new Function<Apple, Integer>() {
    @Override
    public Integer apply(Apple apple) {
        return apple.getColor();
    }
};

此外
List<String> colors = apples.stream()
                            .map(Apple::getColor)
                            .collect(Collectors.toList());

等同于:

List<String> colors = apples.stream()
                            .map(apple -> apple.getColor())
                            .collect(Collectors.toList());

3
这在教程方法引用中有明确的记录,被称为特定类型任意对象实例方法的引用。由于对象具有引用方法类型的类型,因此该对象将是调用方法的对象。这意味着:
map( Apple::getColor )

等同于:

map( a -> a.getColor() )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接