Ссылка на метод java 8 за сценой

Мой вопрос лямбда и ссылки на методы все о функциональных интерфейсах. они просто обеспечивают их реализацию.

Теперь, когда я пишу:

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());

как это на самом деле работает мой геттер не принимает никаких параметров Apple? потому что в соответствии с функциональным интерфейсом функции

@FunctionalInterface
public interface Function<T, R> {
R apply(T t);}

он ожидает параметр и возвращает что-то, и он на самом деле должен работать, когда получатель похож на:

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

я немного растерялся, спасибо заранее

2 ответа

Решение

Такой Function<Apple, Integer> не следует путать с экземпляром Apple,

Помните функции из школы?
Вы должны взять один элемент из домена (здесь яблоко из Apples) и он будет сопоставлен ровно одному соответствующему элементу из домена (здесь целое число из 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());

Это четко задокументировано в ссылке "Метод учебника" как " Ссылка на метод экземпляра произвольного объекта определенного типа". Поскольку объект имеет тип ссылочного метода, то этот объект будет вызывать метод. Значит это:

map( Apple::getColor )

эквивалентно:

map( a -> a.getColor() )
Другие вопросы по тегам