Pages

Wednesday, July 4, 2018

Java 8 map(), flatMap() examples

Using map() method

When programming, it is very common, processing data in order to collect some information from a collections of objects. Let's say, we wanted find out the cities from all the employees in a particular company. Our employee class will be as follows. 


public class Employee {
 
    private String name;
    private Integer age;
    private String city;
    private String state; 
    private Department department;
 
    public String getCity() {
         return city;
    }

    public void setCity(String city) {
         this.city = city;
    } 

    public String getState() {
         return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

I didn't include all the attributes for Employee class, but what I need 'city' attribute in this case. 

So now, we have a list of Employee objects and need to find out distinct cities. Let's see the approach before Java 8. Hopefully, you will write a code as follows in order to get distinct cities. 

List<Employee> employeeList = .....
Set<String> cities = new HashSet<String>();
for (Employee emp : employeeList) {
    cities.add(emp.getCity());
}

Java 8 Stream interface introduces map() method which takes a function as an argument. This function is applied to each element in the stream and returns new stream. The code will look like follows.

List<Employee> employeeList = new ArrayList<Employee>();
List<String> cities = employeeList.stream()
                                  .map(Employee::getCity)
                                  .distinct()
                                  .collect(Collectors.toList());

Using flatMap() method 

Java 8 Stream interface introduces flatMap() method which can be used to merge or flatten few streams into a single stream.

Let's take an example. Suppose, we wanted to filter out distinct words in a text file. Look at the following text file.


Sri Lanka is a beautiful country in Indian ocean.
It is totally surrounded by the sea.

In Java 8, we can read a text file using a single line and it will return a Stream of string. Each element of the stream will be a one line of the text file.

Stream<String> lineStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());

If you see the out put of above code by printing 'lineStream' Stream, it will be the lines of the text file. 

Next, we can convert each element of the above Stream into a Stream of words. Then we can use flatMap() method to flatten all Streams of words into a single Stream. If we execute the following code for each element of the 'lineStream' Stream, we will get two Stream of words. See the following code.

line -> Arrays.stream(line.split(" "))

Two Streams of words will be as follows.

Stream 1 : [SriLanka][is][a][beautiful][country][in][Indian][ocean.]} 
Stream 2 : [It][is][totally][surrounded][by][the][sea.]

The flatMap() method can flatten these two into a single Stream of word as follows.

Stream<String> wordStream = lineStream.flatMap(line -> Arrays.stream(line.split(" ")));

If you print the elements of the above 'wordStream', it will be all the words of the text file. But still, you will see duplicate words. You can use distinct() method to avoid the duplicates. Here's the final code.

List<String> wordStream = lineStream.flatMap(line -> Arrays.stream(line.split(" ")))
                                    .distinct()
                                    .collect(Collectors.toList());

If you see closely, you can find the distinct words of a text file just by using two lines of code with Java 8.

0 comments:

Post a Comment

Share

Widgets