I have a code, which is working as required, but I want to re-write it in Java 8.
This code will produce a map.Each list item will have all the servers allocated to it.
public static Map<String, List<String>> agg(){
List<String> list = Arrays.asList("Item A", "Item B", "Item C");
List<String> servers = Arrays.asList("Server A", "Server B", "Server C", "Server D");
Map<String, List<String>> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
ArrayList<String> temp = new ArrayList<>();
for (int j = 0; j < servers.size(); j++) {
temp.add(servers.get(j));
}
map.put(list.get(i), temp);
}
return map;
}
Output
Item C ::[Server A, Server B, Server C, Server D]
Item B ::[Server A, Server B, Server C, Server D]
Item A ::[Server A, Server B, Server C, Server D]
What would be the lambda equivalent?
The double colon (::) operator, also known as method reference operator in Java, is used to call a method by referring to it with the help of its class directly. They behave exactly as the lambda expressions.
A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. The features of Java stream are – A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
With Java 8, Collection interface has two methods to generate a Stream. stream() − Returns a sequential stream considering collection as its source. parallelStream() − Returns a parallel Stream considering collection as its source.
Let's simplify code before converting it to lambda expressions
public static Map<String, List<String>> agg(){
List<String> list = Arrays.asList("Item A", "Item B", "Item C");
List<String> servers = Arrays.asList("Server A", "Server B", "Server C", "Server D");
Map<String, List<String>> map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
map.put(list.get(i), new ArrayList<>(servers));
}
return map;
}
I just simplified creating an array copy.
The pipeline to convert from a form of data to another in Java 8 contains the following steps:
Because your data does not need to be converted, just collected in a different structure, map and reduce are not needed
public static Map<String, List<String>> agg(){
List<String> list = Arrays.asList("Item A", "Item B", "Item C");
List<String> servers = Arrays.asList("Server A", "Server B", "Server C", "Server D");
Function<String, String> keyFunction = key -> key;
Function<String, List<String>> valueFunction = key -> new ArrayList<>(servers);
return list.stream()
.collect(Collectors.toMap(keyFunction, valueFunction));
}
Those functions can be inlined and the result would be:
public static Map<String, List<String>> agg(){
List<String> list = Arrays.asList("Item A", "Item B", "Item C");
List<String> servers = Arrays.asList("Server A", "Server B", "Server C", "Server D");
return list.stream()
.collect(Collectors.toMap(key -> key, key -> new ArrayList<>(servers)));
}
Create a stream of your "items", and collect them into a map where the keys are the objects from that stream, and the values are copies of the server list.
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import static java.util.stream.Collectors.toMap;
...
List<String> servers = Arrays.asList("Server A", "Server B", "Server C", "Server D");
Map<String, List<String>> map = Stream.of("Item A", "Item B", "Item C")
.collect(toMap(Function.identity(), (__) -> new ArrayList<>(servers)));
A simple forEach
approach would be
Map<String, List<String>> output = new HashMap<>();
list.forEach(s -> output.put(s, servers));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With