Java Streams – a first glance introducing map method

Read Time:4 Minute, 9 Second

The functional-like possibilities introduced along with Java 8 have changed the language a lot. It made coding faster and more concise. We can briefly pour our ideas to the code with less lines of code (which is not always the desired thing, I know). Of course we had had JVM languages like Groovy or Scala earlier but it was Java 8 that had brought those functions to the “clean” Java syntax.

It not literally functional programming but it brings some elements of it. We don’t change the object states until we use terminal operations, we can shape the data flow as we wish.

This is a practical article so let’s go to some examples!

Iterating over list and executing some operations on its elements:

package app;

import java.util.Arrays;
import java.util.List;

public class StreamsExample {
    public static void main(String[] args) {

        List<String> words = Arrays.asList("one", "giraffe", "screwdriver", "scala", "java", "rocketzki", "general", "ant");

        for (String word : words) {
            System.out.println(word.length());
        } //using 'classic' foreach loop

        System.out.println("\nUsing streams:\n");

        words.stream().map(String::length).forEach(System.out::println);
        // using streams and method references.


    }
}

Output:

3
7
11
5
4
9
7
3

Using streams:

3
7
11
5
4
9
7
3

So in the first example I have used regualr foreach loop, in the other one I’ve used streams and method references (you can read more about it on my other article).

I’m not going to analyze the regular foreach loop so let’s get to the second one.

Firstly I’ve called stream() method which has returned stream of strings (Stream<String>) and then I used Stream<R> map(Function<? super T, ? extends R> mapper) method on that stream. The map method tranforms one stream to another using a function passed as a parameter. In this example it takes a String and returns it’s length returning the product of the length() method. Then I call forEach(Consumer<? super T> action) method which under the hood works like the regular foreach loop with println() static reference – but in this case the syntax is more concise.

Other example of using map method:

package app;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamsExampleTwo {
    public static void main(String[] args) {

        // Notice that we can instantiate an ArrayList by passing a list to its constructor!
        List<Integer> numbers = new ArrayList<>(Arrays.asList(1, 2, 34, 5, 66, 54, 5, 89, 4, 2, 22, 3567, 785, 34, 12));

        // I assign the result of the collect method to the wordsAndNumbers variable.
        List<String> wordsAndNumbers = numbers.stream()
                .map(x -> "Number:\t" + x).collect(Collectors.toList());

        // Let's see what we've got here after transformation:
        wordsAndNumbers.forEach(System.out::println);

        // I can also chain the map methods - I have transformed numbers back to Integer type using chained map methods.
        List<Integer> numbersAgain = wordsAndNumbers.stream()
                .map(word -> word.substring(0, 3) + ": " + word.substring(word.indexOf("\t")))
                .map(secondWord -> Integer.valueOf(secondWord.substring(secondWord.indexOf("\t")).trim()))
                .collect(Collectors.toList()); 

        numbersAgain.forEach(System.out::println);


    }
}

Output:

Number:	1
Number:	2
Number:	34
Number:	5
Number:	66
Number:	54
Number:	5
Number:	89
Number:	4
Number:	2
Number:	22
Number:	3567
Number:	785
Number:	34
Number:	12
Trimemd a little bit: 
Num: 	1
Num: 	2
Num: 	34
Num: 	5
Num: 	66
Num: 	54
Num: 	5
Num: 	89
Num: 	4
Num: 	2
Num: 	22
Num: 	3567
Num: 	785
Num: 	34
Num: 	12
Integer again: 
1
2
34
5
66
54
5
89
4
2
22
3567
785
34
12

Firstly, I created a list of strings called numbers – notice that I have passed a new list to the constructor of ArrayList class. That’s another way of instantiating lists.

Then I created new reference – wordsAndNumbers and assigned the result of mapping numbers list to it. The collect method is called a terminal operation. It gathers the stream and gives us it’s result using collector given as a parameter – Collestors.toList() in this case – method from the standard java.util package.

The third list stores a result of my next mapping operation (chain of operations actually). Let me explain what am I doing there: first mapper takes each element of wordsAndNumbers list and maps it to the substring(0,3) which gives us: Num: and the number.

In the fourth list I copy over the third mapper and add another map method  – yes, we can chain stream operations and convert it back to integer using substring and parsing those numbers back to Integer type.

So these are the basics. Should you have any questions, comment or reach me via email!

Link to documentation:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

Article featured image by:

“Picture 029” by Wendy Shaky Hands is licensed under CC BY-NC-SA 2.0

Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x