New Features of Eclipse Collections 10.0 — Part 2

Examples of ten new features in the latest major release of the Eclipse Collections library.

Image for post
Image for post
Ten new features in Eclipse Collections 10.0

Summary

In this blog I will cover ten more of the twenty six new features mentioned in the Eclipse Collections 10.0 Release Summary Blog. Part one of the feature blog series covered the first ten feature examples in Eclipse Collections 10.0.

11. Bag.collectWithOccurrences

You can use this method to transform a collection using all of the unique items in the along with their counts. You specific an to transform the items an their counts to some resulting object. In the following example, I will collect the items and their counts into instances.

@Test
public void collectWithOccurences()
{
MutableBag<String> source =
Bags.mutable.with("1", "2", "2", "3", "3", "3");

MutableBag<ObjectIntPair<String>> targetBag =
source.collectWithOccurrences(PrimitiveTuples::pair);

MutableBag<ObjectIntPair<String>> expected =
Bags.mutable.with(
PrimitiveTuples.pair("1", 1),
PrimitiveTuples.pair("2", 2),
PrimitiveTuples.pair("3", 3));

Assert.assertEquals(expected, targetBag);
}

12. Reduce / reduceIfEmpty for Primitive Iterables

The method reduce will apply a two argument (, ) function which returns a long for each element of the collection. This allows for a widening of the result type so as not to overflow on functions like sum. In the case of an empty collection, a will be thrown.

@Test
public void reducePrimitiveIterables()
{
MutableIntList list =
IntLists.mutable.with(1, 2, 3, 4, 5);

long sum = list.reduce(Long::sum);

Assert.assertEquals(15L, sum);
Assert.assertEquals(list.sum(), sum);

Verify.assertThrows(
NoSuchElementException.class,
()-> IntLists.mutable.empty().reduce(Long::sum));
}

If you would like to safely handle the case of empty, you can use and specify a default value to return.

@Test
public void reduceIfEmptyPrimitiveIterables()
{
MutableIntList list =
IntLists.mutable.with(1, 2, 3, 4, 5);

long sum = list.reduceIfEmpty(Long::sum, 0L);

Assert.assertEquals(15L, sum);
Assert.assertEquals(list.sum(), sum);

Assert.assertEquals(0L,
IntLists.mutable.empty()
.reduceIfEmpty(Long::sum, 0L));
}

13. New <T1><T2>To<T1>Function for primitives

In the example above, the method reduce for an takes a new interface names . There are two argument functions for every combination of every primitive type.

@Test
public void newLongTypeToLongFunctions()
{
MutableIntList intList =
IntLists.mutable.with(1, 2, 3, 4, 5);

LongIntToLongFunction sumFunction1 = Long::sum;
long sum1 = intList.reduceIfEmpty(sumFunction1, 0L);

Assert.assertEquals(15L, sum1);

MutableByteList byteList =
ByteLists.mutable.with((byte) 1, (byte) 2, (byte) 3);

LongByteToLongFunction sumFunction2 = Long::sum;
long sum2 = byteList.reduceIfEmpty(sumFunction2, 0L);

Assert.assertEquals(6L, sum2);
}

14. Of/withInitialCapacity to Primitive Maps

You can now construct a primitive map with an initial capacity using or on the primitive map factories.

@Test
public void ofAndWithInitialCapacity()
{
MutableIntIntMap map1 =
IntIntMaps.mutable.ofInitialCapacity(100);

MutableIntIntMap map2 =
IntIntMaps.mutable.withInitialCapacity(100);

Assert.assertEquals(map1, map2);
}

15. RichIterable.countByEach

The method is similar to and . All three take a which returns an . The result in the case of is a . In the following example, I count all of the methods by their names for three classes. The count of methods will include overloads and overrides of the methods.

@Test
public void countByEach()
{
MutableList<Class<?>> classes =
Lists.mutable.with(
RichIterable.class,
MutableList.class,
ImmutableList.class);

Bag<String> methodNames =
classes.countByEach(each ->
ArrayAdapter.adapt(each.getMethods())
.collect(Method::getName));

Assert.assertEquals(8,
methodNames.occurrencesOf("countByEach"));
Assert.assertEquals(16,
methodNames.occurrencesOf("groupByEach"));
Assert.assertEquals(2,
methodNames.occurrencesOf("sortThis"));
}

16. UnifiedSetWithHashingStrategy.addOrReplace

The method on a will replace a value in the if it already exists. This is different than calling add which will not replace a value in a if it already exists.

@Test
public void addOrReplace()
{
UnifiedSetWithHashingStrategy<Integer> set =
new UnifiedSetWithHashingStrategy<>(
HashingStrategies.defaultStrategy());
Integer one = new Integer(1);
set.addOrReplace(one);
Assert.assertSame(one, set.get(1));
set.add(new Integer(1));
Assert.assertSame(one, set.get(1));
Integer otherOne = new Integer(1);
set.addOrReplace(otherOne);
Integer integer = set.get(otherOne);
Assert.assertSame(otherOne, integer);
Assert.assertNotSame(one, integer);
}

17. UnmodifiableMutableOrderedMap

If you call on a , you will get an instance returned.

@Test
public void unmodifiableMutableOrderedMap()
{
MutableOrderedMap<Object, Object> map =
OrderedMaps.adapt(new LinkedHashMap<>())
.asUnmodifiable();

Verify.assertInstanceOf(
UnmodifiableMutableOrderedMap.class,
map);
}

18. WithAllKeyValues on mutable primitive maps

There is a new method on primitive maps that allows you to put multiple pairs of keys and values into the at once.

@Test
public void withAllKeyValues()
{
MutableIntIntMap map =
IntIntMaps.mutable.empty()
.withAllKeyValues(
Lists.mutable.with(
PrimitiveTuples.pair(1, 1),
PrimitiveTuples.pair(2, 2),
PrimitiveTuples.pair(3, 3)
))
.withAllKeyValues(
Lists.mutable.with(
PrimitiveTuples.pair(4, 4),
PrimitiveTuples.pair(5, 5)
));

MutableIntIntMap expected = IntIntMaps.mutable.empty()
.withKeyValue(1, 1)
.withKeyValue(2, 2)
.withKeyValue(3, 3)
.withKeyValue(4, 4)
.withKeyValue(5, 5);

Assert.assertEquals(expected, map);
}

19. Create Primitive Map from Iterable

You can now create a primitive from an with two provided . One is used to calculate the key, and the other is used to calculate the value. This method is very similar the method on . The difference is that it works with any primitive .

@Test
public void createPrimitiveMapFromIterable()
{
Iterable<Integer> integers = Interval.oneTo(5);
MutableIntIntMap map =
IntIntMaps.mutable.from(
integers,
key -> key,
value -> value);

MutableIntIntMap expected = IntIntMaps.mutable.empty()
.withKeyValue(1, 1)
.withKeyValue(2, 2)
.withKeyValue(3, 3)
.withKeyValue(4, 4)
.withKeyValue(5, 5);

Assert.assertEquals(expected, map);
}

20. HashingStrategySets.of/withInitialCapacity

You can now create a using of or on the factory.

@Test
public void hashingStrategySetsOfOrWithInitialCapacity()
{
MutableSet<Object> set1 =
HashingStrategySets.mutable.ofInitialCapacity(
HashingStrategies.defaultStrategy(),
100);

MutableSet<Object> set2 =
HashingStrategySets.mutable.withInitialCapacity(
HashingStrategies.defaultStrategy(),
100);

Assert.assertEquals(set1, set2);
}

Stay Tuned!

There are still six more features to cover in Eclipse Collections 10.0. I will be writing one more blog covering the final set of them.

I hope you enjoy all of the new features in Eclipse Collections 10.0!

Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.

Written by

Java Champion. Creator of the Eclipse Collections OSS Java library (http://www.eclipse.org/collections/). Inspired by Smalltalk. Opinions are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store