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
50
To 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
50
Squaring 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
25
Map 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
25
Mapping 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!