Eclipse Collections is an open source Java Collections framework. In this blog I am going to demonstrate four lesser known features of the framework. I have published similar blogs in Java Advent Calendars of 2018, 2019, 2020, 2021, 2022, 2023, and 2024. Please refer to the resources at the end of the blog for more information about the framework. The newly published Eclipse Collections Categorically: Level up your programming game is a great book to dive deep in the design and methodology behind the iteration patterns of Eclipse Collections.
groupByUniqueKey(): Eclipse Collections offers a way to transform and collect the output in a map, where the key is the transformed value. ThegroupByUniqueKey()API ensures that the generated keys must each be unique, or else an exception is thrown. This is an easy way to create a map from a collection and guarantee that no keys are overridden.@Test public void groupByUniqueKey() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableMap<Integer, Integer> groupByUniqueKeyMap = list.groupByUniqueKey( each -> -1 * each); // Negate each integer MutableMap<Integer, Integer> expectedMap = Maps.mutable.of( -1, 1, //key, value pairs -2, 2, -3, 3, -4, 4); assertEquals(expectedMap, groupByUniqueKeyMap); } @Test public void groupByUniqueKey_throws() { MutableList list = Lists.mutable.of(1, 2, 2, 3); // Throws exception because the element 2 is a duplicate assertThrows( IllegalStateException.class, () -> list.groupByUniqueKey(each -> each)); }countByEach(): Eclipse Collections offers a way to count the number of occurrences of each value after transforming each element of a collection. ThecountByEach()API does it by iterating through the collection and applying the function to each element and then counting the number of occurrences of the transformed value. This API returns aBagwhich is an optimized data structure for counting number of objects. This is similar to thecountBy()API that I covered in the 2019 blog with the difference that in case ofcountByEach()the transformation function returns anIterable@Test public void countByEach() { MutableList<Integer> list = Lists.mutable.of(1, 2, 3, 4); MutableBag<Integer> counts = list .countByEach( each -> Lists.mutable.of(each, each + 1)); assertEquals(1, counts.occurrencesOf(1)); assertEquals(2, counts.occurrencesOf(2)); assertEquals(2, counts.occurrencesOf(3)); assertEquals(2, counts.occurrencesOf(4)); assertEquals(1, counts.occurrencesOf(5)); }-
sumBy*(): Eclipse Collections offers a way to group and sum elements of the collection usingsumByInt(),sumByLong(),sumByDouble(), andsumByFloat()methods. A salient point to note is that the return types are up-casted i.e.sumByInt()returns aObjectLongMapandsumByFloat()returns aObjectDoubleMap. This avoids overflow issues in the results.// Common function to classify even and odd numbers Function<Integer, String> mappingFunction = each -> { if (each % 2 == 0) { return "EVEN"; } return "ODD"; }; @Test public void sumByInt() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableObjectLongMap sumByInt = list.sumByInt( mappingFunction, each -> each); MutableObjectLongMap expected = ObjectLongMaps.mutable.of( "EVEN", 6L, //key, value pairs "ODD", 4L); assertEquals(expected, sumByInt); } @Test public void sumByLong() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableObjectLongMap sumByLong = list.sumByLong( mappingFunction, Integer::longValue); MutableObjectLongMap expected = ObjectLongMaps.mutable.of( "EVEN", 6L, //key, value pairs "ODD", 4L); assertEquals(expected, sumByLong); } @Test public void sumByDouble() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableObjectDoubleMap sumByDouble = list.sumByDouble( mappingFunction, Integer::doubleValue); MutableObjectDoubleMap expected = ObjectDoubleMaps.mutable.of( "EVEN", 6.0, //key, value pairs "ODD", 4.0); assertEquals(expected, sumByDouble); } @Test public void sumByFloat() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableObjectDoubleMap sumByFloat = list.sumByFloat( mappingFunction, Integer::floatValue); MutableObjectDoubleMap expected = ObjectDoubleMaps.mutable.of( "EVEN", 6.0, //key, value pairs "ODD", 4.0); assertEquals(expected, sumByFloat); } aggregateBy(): Eclipse Collections offers a way to aggregate and group results into a map using a grouping function. Please note the API signature — the first input is the grouping function, second input is the zero value function, and the last input is the aggregation function. The code below shows how each of these inputs impacts the behavior.@Test public void aggregateBy() { MutableList list = Lists.mutable.of(1, 2, 3, 4); MutableMap<String, Integer> aggregateBy1 = list.aggregateBy( mappingFunction, () -> 0, Integer::sum); // Note that because the zero value is in this case 0, // the result is that // sum of even numbers is 0 + 2 + 4 = 6; // sum of odd numbers is 0 + 1 + 3 = 4 MutableMap<String, Integer> expected1 = Maps.mutable.of( "EVEN", 6, "ODD", 4); assertEquals(expected1, aggregateBy1); MutableMap<String, Integer> aggregateBy2 = list.aggregateBy( mappingFunction, () -> 10, Integer::sum); // Note that because the zero value is in this case 10, // the result is that // sum of even numbers is 10 + 2 + 4 = 16; // sum of odd numbers is 10 + 1 + 3 = 14 MutableMap<String, Integer> expected2 = Maps.mutable.of( "EVEN", 16, "ODD", 14); assertEquals(expected2, aggregateBy2); MutableMap<String, Integer> aggregateBy3 = list.aggregateBy( mappingFunction, () -> 0, (before, each) -> before + each + 10); // Note that because the aggregation function adds 10 to // every computation, the computation becomes: // for even numbers: 0 + (2 + 10) + (4 + 10) = 26; // for odd numbers: 0 + (1 + 10) + (3 + 10) = 24 MutableMap<String, Integer> expected3 = Maps.mutable.of( "EVEN", 26, "ODD", 24); assertEquals(expected3, aggregateBy3); }
Summary:
groupByUniqueKey(), countByEach(), sumBy*(), and aggregateBy(). I hope you found the post informative. If you have not used Eclipse Collections before, give it a try. There are few resources below. Make sure you show us your support and put a star on our GitHub Repository.Eclipse Collections Resources
- Website
- Source code on GitHub (Make sure to star the Repository)
- Contribution Guide
- Reference Guide
- Eclipse Collections Categorically: Level up your programming game
steinhauer.software