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