Ищу глубокое понимание функции - PullRequest
0 голосов
/ 20 октября 2019

Ниже показан пример кода, который использует потоки Java. Мой вопрос конкретно относится к Interface Function<T,R>, который принимает ввод типа T и возвращает что-то типа R.

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.groupingBy;

import java.util.List;
import java.util.Map;

public class Dish {

  private final String name;
  private final boolean vegetarian;
  private final String calories;

  public Dish(String name, boolean vegetarian, String calories) {
    this.name = name;
    this.vegetarian = vegetarian;
    this.calories = calories;
  }

  public String getName() {
    return name;
  }

  public boolean isVegetarian() {
    return vegetarian;
  }

  public String getCalories() {
    return calories;
  }

  @Override
  public String toString() {
    return name;
  }

  public static final List<Dish> menu = asList(
      new Dish("pork", false, "GE 600"),
      new Dish("beef", false, "GE 600"),
      new Dish("chicken", false, "300-600"),
      new Dish("french fries", true, "300-600"),
      new Dish("rice", true, "LE 300"),
      new Dish("season fruit", true, "LE 300"),
      new Dish("pizza", true, "300-600"),
      new Dish("prawns", false, "300-600"),
      new Dish("salmon", false, "300-600")
  );

  public static void main(String[] args) {
        Map<String, List<Dish>> dishByCalories = menu.stream()
                .collect(groupingBy(Dish::getCalories));
        System.out.println(dishByCalories);
  }
}

Очевидно, groupingBy(Dish::getCalories) удовлетворяет ожидаемым требованиям к сигнатуре метода collect (т. Е. Collector<? super T,A,R> collector)

Теперь перейдя к groupingsBy, его требования к подписи следующие:
static <T,K> Collector<T,?,Map<K,List<T>>> groupingBy(Function<? super T,? extends K> classifier)

Ссылка на метод, которую мы передаем groupingsBy: Dish::getCalories

Очевидно, Dish::getCalories удовлетворяет требованиям подписи Function<? super T,? extends K> (т.е. принять вход некоторого суперкласса T и вернуть результат некоторого подкласса K).

Однако метод getCalories не принимает аргументов и возвращает строку.

Пожалуйста, помогите очистить мое замешательство.

1 Ответ

5 голосов
/ 20 октября 2019

getCalories - это метод instance , поэтому он принимает неявный аргумент this.

Dish::getCalories эквивалентен лямбде (Dish dish) -> dish.getCalories(), что делает его реализациейFunction<Dish, String>.

...