Локальные классы с лямбда-выражениями

Как я уже проверял, приведенный ниже код выполняется без проблем. Но я не мог понять логику. Может кто-нибудь объяснить, пожалуйста?

public static void main(String[] args) {
    List<String> london = new ArrayList<>(Arrays.asList("Chinatown","Croydon","Eden Park"));
    class City{
        private String name;
        City(String name){
            this.name = name;
        }

        public void printCity(){
            System.out.println(name);
        }
    }

    london.stream().map(City::new).forEach(City::printCity); //Chinatown,Croydon,Eden Park
}

В приведенном выше примере кода у меня есть следующие вопросы.

  1. Метод foreach всегда принимает потребительский объект. Здесь метод printCity не является методом, который принимает аргумент. Все еще это работает. Как?
  2. Метод printCity не является здесь статическим методом. Как сам город может вызывать метод экземпляра?

2 ответа

Решение

Потребитель эквивалентен чему-то вроде c -> c.printCity(), (City c) -> c.printCity()или какой-то длинный анонимный класс, который очень тяжело печатать.

Городские экземпляры являются предметом вызова. Есть только синтаксический сахар в виде City::printCity который передает метод в выражение, где вызывается экземпляр.

В своем последнем утверждении вы в настоящее время использовали ссылки на методы. Это может быть альтернативно написано следующим образом:

london.stream().map(name -> new City(name)).forEach(city -> city.printCity());

Как вы можете видеть выше, map возвращается City экземпляров. Так forEach получает City экземпляры и звонки printCity в каждом случае.

При использовании ссылок на методы, City::printCity это не то же самое, что звонить City.printCity, Смотрите документацию по методике

Ссылки на методы - это просто удобочитаемые лямбда-выражения.

Другие вопросы по тегам