Локальные классы с лямбда-выражениями
Как я уже проверял, приведенный ниже код выполняется без проблем. Но я не мог понять логику. Может кто-нибудь объяснить, пожалуйста?
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
}
В приведенном выше примере кода у меня есть следующие вопросы.
- Метод foreach всегда принимает потребительский объект. Здесь метод printCity не является методом, который принимает аргумент. Все еще это работает. Как?
- Метод 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
, Смотрите документацию по методике
Ссылки на методы - это просто удобочитаемые лямбда-выражения.