This time, I will show you how to use collectors along with streams to group by, concatenate, map, and list.
Example: Convert a list of elements to a string separated by ‘,’
import java.util.List;
import java.util.stream.Collectors;
public class StreamToStringConverter {
private String parse(){
return List.of("Java", "C++", "Lisp", "Haskell").
stream().collect(Collectors.joining(","));
}
public static void main(String[] args){
var result = new StreamToStringConverter().parse();
assert "Java,C++,Lisp,Haskell".equals(result);
}
}
From a list, generate another list selecting elements if the string length equals four.
import java.util.List;
import java.util.stream.Collectors;
public class StreamToListConverter {
private List<String> parse(){
return List.of("Java", "C++", "Lisp", "Haskell").
stream().filter( it -> it.length() == 4 ).toList();
}
public static void main(String[] args){
var result = new StreamToListConverter().parse();
assert 2 == result.size();
assert result.contains("Java");
assert result.contains("Lisp");
}
}
From a list of strings get a map with string element as key and string length as value
import java.util.Map;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
public class StreamToMapConverter {
private Map<String, Integer> parse(){
return List.of("Java", "C++", "Lisp", "Haskell").
stream().collect(Collectors.toMap(Function.identity(), String::length));
}
public static void main(String[] args){
var result = new StreamToMapConverter().parse();
assert 4 == result.size();
assert result.get("Java") == 4;
assert result.get("C++") == 3;
assert result.get("Lisp") == 4;
assert result.get("Haskell") == 7;
}
}
Function.identity()
is a convenient way to express a function returning the same value as the input. This is useful when a function is expected, but you do not want to perform any operation to transform the input. String::length
is a shortcut to call a class method directly; this behaves exactly as the lambda expression it -> it.lenght()
Example: From a list of persons, group by role.
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GroupByCollector {
private Map<RoleType, List<Person>> parse(List<Person> persons){
return persons.stream().collect(Collectors.groupingBy(Person::getType));
}
public static void main(String[] args){
var persons = List.of(
new Person("josdem", RoleType.DEVELOPER),
new Person("tgtip", RoleType.DEVELOPER),
new Person("erich", RoleType.TESTER)
);
var result = new GroupByCollector().parse(persons);
assert result.get(RoleType.DEVELOPER).size() == 2;
assert result.get(RoleType.TESTER).size() == 1;
}
}
class Person {
String name;
RoleType type;
public Person(String name, RoleType type){
this.name = name;
this.type = type;
}
RoleType getType(){
return type;
}
}
enum RoleType {
DEVELOPER, TESTER
}
To browse the code go here, to download the code:
git clone https://github.com/josdem/java-workshop.git
cd streams/collect
To run the code:
javac ${JAVA_PROGRAM}.java
java -ea ${JAVA_PROGRAM}