Lambda expressions - part 2

As we saw in our first post : Lambda expressions part 1, Java 8 came with some cool new features.
One of them is lambdas expressions; another one is streams.
What is a stream? A sequence of elements. Unlike a collection, which has an structure to hold the objects, a stream carries the values of those objects. With streams we can use also 'aggregate operations' like  filtermap or forEach.These operations process elements from a stream and not from a collection.
Let's say we have our musician entity


import lombok.Data;
@Data
public class Musician {

    public enum INSTRUMENT{
        GUITAR, DRUMS, BASS, VOICE, KEYBOARDS    }

    private String firstName;
    private String lastName;
    private INSTRUMENT instrument;
}

and then we create our musician List

public class TestLambda {

    List<Musician> musicians = new ArrayList<>();
    public void testMusicians(){

       musicians.add(createMusician("Peter", "Gabriel", 
        Musician.INSTRUMENT.VOICE));
        musicians.add(createMusician("Tony","Banks", 
        Musician.INSTRUMENT.KEYBOARDS));
        musicians.add(createMusician("Phil","Collins", 
        Musician.INSTRUMENT.DRUMS));        
        musicians.add(createMusician("Steve", "Hackett", 
        Musician.INSTRUMENT.GUITAR));

    }


    private Musician createMusician(String firstName, String lastName, 
        Musician.INSTRUMENT instrument){

        Musician musician = new Musician();        
        musician.setFirstName(firstName);        
        musician.setLastName(lastName);        
        musician.setInstrument(instrument);        
        return musician;     
    
}

}

If we need just to obtain the musicians whose first name starts with "P" and then collect their first names on a new list

List<String> firstNames =
        musicians.stream().filter( m ->
                            m.getFirstName().startsWith("P"))
                            .map(Musician::getFirstName)
                            .collect(Collectors.toList());
firstNames.forEach(n -> System.out.println("First name: " + n));

You can get
First name: Peter 

First name: Phil


We don't need a lot of lines of code to filter the information we need.
As you can see in our example the filter() function allows us to select whatever we need from the list on the fly whereas the map() function let us transform part of that response on a String, and then finally collect() let us create a new collection with the results .

We can even create a new Map<String, Musician> with the result instead of having a List .
Come again? Yes, you can start with a List of objects and end up with a Map of a selection of that list with a simple...
Map<String, Musician> firstNames =
        musicians.stream().filter( m ->
                            m.getFirstName().startsWith("P"))
                            .collect(Collectors.toMap(m -> m.getFirstName(),
                            m->m));

firstNames.forEach((k,v) -> System.out.println("First name: " + k +  ", Last name: " +
 v.getLastName()));

In our example, the keys for the Map are the first names of our beloved musicians, but you can put whatever you need.


First name: Peter, Last name: Gabriel 
First name: Phil, Last name: Collins
 


Process finished with exit code 0

One of the benefits of stream operations is that they do the iteration for you, you don't need to explicitly iterate - like you should it with a collection.

As this excellent article about Java streams explain, you can see the stream operations as  sophisticated data processing queries.

Another cool feature that comes with Java 8 - Functional Interfaces: a functional interface is an interface with exactly one abstract method.
Java 8 comes with new functional interfaces in the package java.util.function.
For example, Function<T,R>  takes an object of type T, and returns R.

Function<String, Integer> length = (name) -> name.length();

musicians.forEach(m -> System.out.println("first name: " + m.getFirstName() +

             ", length: " + length.apply(m.getFirstName())));

it gives us

first name: Peter, length: 5

first name: Tony, length: 4

first name: Phil, length: 4

first name: Steve, length: 5



That's it for today !

Comments

Popular Posts