Next up in our series exploring functional programming in java 8, the map method.
Getting started
The map method is a transform operation and is a functional programming technique that applies a function to each one of a streams elements returning the results. A common use case map is utilized for is transforming object in java.
Starting simple
For our first snippet, lets multiply each element in the list by 10 by passing in a lambda function to the Stream.map() that accepts a parameter then multiples it by 10. Next, to display the results by using java8 print stream.
@Test
public void map_times_10() {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> multipleOf10 = myList.stream().map((x) -> x * 10);
multipleOf10.forEach(System.out::println);
}Output
10
20
30
40
50To be more usable, we can refactoring our code by moving the lambda expression and declare a function. In addition, if we were returning a list as a data type, we can convert the stream to list and then again, output the values in the list where we should see the same result as above.
@Test
public void map_times_10_refactor() {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
Function<Integer, Integer> times10 = (x) -> x * 10;
List<Integer> multipleOf10 = myList.stream().map(times10)
.collect(Collectors.toList());
multipleOf10.forEach(System.out::println);
}Output
10
20
30
40
50Squaring values
Similar in fashion, lets create a function that will square all the values within a stream. We will create a java 8 function that accepts one parameter and then multiplies it by itself. Next we will Stream.collect(), a reduction operation, the result of the map and convert the stream to a set.
@Test
public void map_square_to_set() {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
Function<Integer, Integer> square = (x) -> x * x;
Set<Integer> squaresList = myList.stream().map(square)
.collect(Collectors.toSet());
squaresList.forEach(System.out::println);
}Output
16
1
4
9
25Map one object to another
If you are looking for a way to convert from object A to object B java 8 makes it easy. Below we will show how to convert a list to map by first creating a POJO named JavaScriptFrameworks. Next initializing a List with three objects we will use a stream() to call the Collectors.toMap. The first parameter will accept a function that will generate the key while second parameter will generate the value. Finally we will loop over the elements using the for each
class JavaScriptFrameworks {
private Integer rank;
private String description;
public JavaScriptFrameworks(Integer rank, String description) {
super();
this.rank = rank;
this.description = description;
}
}
@Test
public void objectAObjectB() {
List<JavaScriptFrameworks> framework = new ArrayList<JavaScriptFrameworks>();
framework.add(new JavaScriptFrameworks(1, "Angular"));
framework.add(new JavaScriptFrameworks(2, "React"));
framework.add(new JavaScriptFrameworks(3, "EmberJs"));
Map<Integer, JavaScriptFrameworks> mappedFramework = framework.stream()
.collect(
Collectors.toMap(JavaScriptFrameworks::getRank,
(p) -> p));
mappedFramework.forEach((k, v) -> System.out.println("rank = " + k
- " value = " + v));
}Output
rank = 1 value = JavaScriptFrameworks [rank=1, description=Angular]
rank = 2 value = JavaScriptFrameworks [rank=2, description=React]
rank = 3 value = JavaScriptFrameworks [rank=3, description=EmberJs]Java 8 primitive streams
If you are working within your favorite ide, you will notice three other map methods exists. mapToInt, mapToDouble, and mapToLong are methods designed to return primitive data streams. This is helpful if you are looking to perform a reduce operations on a stream.
Building on the squares snippet above passing in square function to map will produce a stream of Integers. Then calling mapToInt will return an IntStream where we can call max to return the maximum value in stream.
@Test
public void mapto() {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
Function<Integer, Integer> square = (x) -> x * x;
IntStream squaresIntStream = myList.stream().map(square)
.mapToInt(Integer::intValue);
System.out.println(squaresIntStream.max().getAsInt());;
}Output
25Mapping values using guava
Before java 8, you were left with transforming values in java using a imperative programming technique unless you were using a library such as guava. If you are familiar with the library, the code below will provide an example for reference.
@Test
public void map_square_guava() {
List<Integer> myList = Arrays.asList(1, 2, 3, 4, 5);
//com.google.common.base.Function
Function<Integer, Integer> square = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer value) {
return value * value;
}
};
List<Integer> squaresList = FluentIterable.from(myList)
.transform(square).toList();
System.out.println(squaresList);
}Output
[1, 4, 9, 16, 25]Converting from object to object or primitive streams, this tutorial scratched the surface in showing basic ways to use Stream.map function. Thanks for joining in today's levelup, have a great day!