2

I've seen two different ways to iterate a list in java8.

case 1:

List<String> names = Arrays.asList("Rakesh", "Amal", "Ramez", "Sreejith");
names.forEach(name -> System.out.println(name));

case 2:

List<String> names = Arrays.asList("Rakesh", "Amal", "Ramez", "Sreejith");
names.forEach(System.out::println);

case 1 is by using Lambda expressions And case 2 with method reference ::

Can any one explain more on these two cases ?

Rakesh KR
  • 6,357
  • 5
  • 40
  • 55
  • 5
    Well what don't you understand about them at the moment? Do you understand lambdas, method references and functional interfaces? If not, that would be the first set of topics to research... – Jon Skeet Jul 05 '14 at 06:44

2 Answers2

4

First you need to know how forEach is defined:

void forEach(Consumer<? super T> action)

The documentation states that the default implementation behaves like:

for (T t : this)
    action.accept(t);

A Consumer<T> is a functional interface that:

Represents an operation that accepts a single input argument and returns no result..

The specified action can be called using lambda syntax. If there is a class like this:

class Person
{
    String Name
    int Age
}

and an action that uses this class Consumer<Person>, then it can be used/called like this:

p -> p.Name

The first variant using the lambda syntax is applying the specified method (in this case System.out.println) to the parameter name. You can read the line as:

for each name from the list names do System.out.println(name)

The second variant is using the nature of the Consumer inerface in order to apply the function to every item of the list without the need to specify the parameter explicitly, because this is done automatically (because of the matching signature) and it is called Method Reference.

So this allows a call to a method expecting only one Consumer<T> argument:

This is a functional interface whose functional method is accept(Object)..

And in this case the forEach construct happens to be one such method and that is why the parameter name could be omitted from the call, thus leading to the syntax:

list.forEach(someMethodWithOneParameterOnly);

In background the call is transformed again to:

for each item from list do someMethodWithOneParameterOnly(item)

keenthinker
  • 7,645
  • 2
  • 35
  • 45
2

A lambda expression is an anonymous method: a piece of code that can be called.

Case 1: The forEach method of List is going to call the lambda expression for each element in the list. Each time the lambda is called, name will refer to the element in the list that it's called for.

Case 2: Instead of an anonymous method (a lambda expression), you can also pass a reference to an existing, named method, in this case the println method of System.out. Now, forEach is going to call that method for each element in the list. Note that the name parameter is now not explicitly mentioned.

Jesper
  • 202,709
  • 46
  • 318
  • 350