Java 8 Collections Utilities
Multiple Sort using streams
Prior to java 8 when you tried to sort by several comparators, it got ugly fast. So you might of created a single comparator with logic to compare various fields and the code readability goes down the tube. What is neat about java 8 is it implemented a way to concatenate or combine multiple comparators together by calling Comparator.thenComparing.
We will first create two comparators byFirstName and byLastName. Since we want first name sorted first we will call the thenComparing method on the byFirstName comparator. The thenComparing method will then return a comparator which we will pass into the sort method.
@Test
public void multiple_sort() {
Comparator<Employee> byFirstName = (e1, e2) -> e1
.getEmployeeFirstName().compareTo(e2.getEmployeeFirstName());
Comparator<Employee> byLastName = (e1, e2) -> e1.getEmployeeLastName()
.compareTo(e2.getEmployeeLastName());
employees.stream().sorted(byFirstName.thenComparing(byLastName))
.forEach(e -> System.out.println(e));
}
or we can write the comparator as
@Test
public void multiple_sort() {
Comparator<Employee> byFirstName =
Comparator.comparing(Employee::getEmployeeFirstName);
Comparator<Employee> byLastName = Comparator.comparing(Employee::getEmployeeLastName);
employees.stream().sorted(byFirstName.thenComparing(byLastName))
.forEach(e -> System.out.println(e));
}
Comparing the Keys of Two Maps and storing in a new Map
Here we can use a Comparable as well as a Comparator depending based on the ordering required
To sort in reverse order, pass Comparator.reverseOrder()
as parameter to comparingByValue
.
To get a LinkedHashMap
, you must specifically request one with the 4-argument toMap()
. If you don't specify what kind of a map you want, you will get whatever the default is, which currently happens to be a HashMap
. Since HashMap
doesn't preserve the order of elements, it will definitely not do for you.
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x,y)-> {throw new AssertionError();},
LinkedHashMap::new
));
Similarly for comparing the values of two maps, we can use
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x,y)-> {throw new AssertionError();},
LinkedHashMap::new
));