Local classes with Lambda expressions

147 Views Asked by At

As I tested, the below code executes without any issues. But I could not understand the logic. Can someone please explain?

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
}

In the above example code, I have following questions.

  1. The foreach method always takes a consumer object. In here printCity method is not a method that takes an argument. Still it works. How?
  2. printCity method is not a static method here. How a City itself can call a instance method?
2

There are 2 best solutions below

0
ifly6 On BEST ANSWER

The consumer is equivalent to something like c -> c.printCity(), (City c) -> c.printCity(), or some long anonymous class that is a massive pain to type out.

The city instances are the subject of invocation. There is just syntactical sugar in the form of City::printCity which passes the method to the expression, where the instance is called.

1
curlyBraces On

In your last statement you have currently used method references. This can be alternatively written as following:

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

As you can see above, the map returns City instances. So forEach gets City instances and calls printCity on each instance.

When using method references, City::printCity is not the same as calling City.printCity. See Method References documentation

Method references are just easy-to-read lambda expressions.