New Features of Eclipse Collections 10.0 — Part 1
Examples of ten new features in the latest major release of the Eclipse Collections library
Summary
In this blog I will cover ten of the twenty six new features mentioned in the Eclipse Collections 10.0 Release Summary Blog.
1. MultiReaderList/Bag/Set Interfaces
We have had multi-reader collection implementations for a long time. We have not had specialized interfaces for them. Now we do.
@Test
public void multiReaderList()
{
MultiReaderList<String> list =
Lists.multiReader.with("1", "2", "3");
list.withWriteLockAndDelegate(backingList -> {
Iterator<String> iterator = backingList.iterator();
iterator.next();
iterator.remove();
}); Assert.assertEquals(Lists.mutable.with("2", "3"), list);
}
2. Stream for Primitive Lists
You can ask for a Stream
from a regular List
, but prior to Eclipse Collections 10.0, you could not easily get a primitive Stream
from a primitive List
. Now you can.
@Test
public void primitiveListToPrimitiveStream()
{
IntStream intStream1 =
IntLists.mutable.with(1, 2, 3, 4, 5)
.primitiveStream();
IntStream intStream2 =
IntLists.immutable.with(1, 2, 3, 4, 5)
.primitiveStream();
LongStream longStream1 =
LongLists.mutable.with(1L, 2L, 3L, 4L, 5L)
.primitiveStream();
LongStream longStream2 =
LongLists.immutable.with(1L, 2L, 3L, 4L, 5L)
.primitiveStream();
DoubleStream doubleStream1 =
DoubleLists.mutable.with(1.0, 2.0, 3.0, 4.0, 5.0)
.primitiveStream();
DoubleStream doubleStream2 =
DoubleLists.immutable.with(1.0, 2.0, 3.0, 4.0, 5.0)
.primitiveStream();
}
3. toMap supports passing a target Map
The method toMap
has been overloaded to allow a target Map
to be passed in as a parameter.
@Test
public void toMapWithTarget()
{
MutableList<Integer> list =
Lists.mutable.with(1, 2, 3, 4, 5);
Map<String, Integer> map =
list.toMap(String::valueOf,
each -> each,
new LinkedHashMap<>());
Map<String, Integer> expected = new LinkedHashMap<>();
expected.put("1", 1);
expected.put("2", 2);
expected.put("3", 3);
expected.put("4", 4);
expected.put("5", 5);
Assert.assertEquals(expected, map);
}
4. MutableMapIterable removeAllKeys
With Eclipse Collections 10.0, you can removeAllKeys
from a Map
that are contained in the specified Set
parameter.
@Test
public void removeAllKeys()
{
MutableMap<Integer, String> map =
Maps.mutable.with(1, "1", 2, "2", 3, "3");
map.removeAllKeys(Sets.mutable.with(1, 3));
Assert.assertEquals(Maps.mutable.with(2, "2"), map);
}
5. RichIterable toBiMap
With Eclipse Collections 10.0, you can now convert any RichIterable
to a BiMap
.
@Test
public void toBiMap()
{
MutableBiMap<String, Integer> expected =
BiMaps.mutable.with("1", 1, "2", 2, "3", 3);
MutableBiMap<String, Integer> biMap =
Lists.mutable.with(1, 2, 3).toBiMap(String::valueOf, i -> i);
Assert.assertEquals(expected, biMap);
}
6. MultiMap collectKeyMultiValues
We can now transform a Multimap
applying functions to both keys and values using collectKeyMultiValues
.
@Test
public void collecKeyMultiValues()
{
MutableListMultimap<String, String> multimap =
Multimaps.mutable.list.with(
"nj", "Monmouth",
"nj", "Bergen",
"nj", "Union");
MutableBagMultimap<String, String> transformed =
multimap.collectKeyMultiValues(
String::toUpperCase,
String::toUpperCase);
Assert.assertEquals(Multimaps.mutable.bag.with(
"NJ", "MONMOUTH",
"NJ", "BERGEN",
"NJ", "UNION"), transformed);
}
7. fromStream on Collection Factories
We can now construct a Collection
from a Stream
using fromStream
on each of the Collection
factories for List
, Set
, Bag
, and Stack
.
@Test
public void fromStreamOnCollectionFactories()
{
MutableList<Integer>
list = Lists.mutable.fromStream(Stream.of(1, 2, 3, 4, 5));
Assert.assertEquals(
Lists.mutable.with(1, 2, 3, 4, 5), list);
MutableSet<Integer> set =
Sets.mutable.fromStream(Stream.of(1, 2, 3, 4, 5));
Assert.assertEquals(
Sets.mutable.with(1, 2, 3, 4, 5), set);
MutableBag<Integer> bag =
Bags.mutable.fromStream(Stream.of(1, 2, 3, 4, 5));
Assert.assertEquals(
Bags.mutable.with(1, 2, 3, 4, 5), bag);
MutableStack<Integer> stack =
Stacks.mutable.fromStream(Stream.of(1, 2, 3, 4, 5));
Assert.assertEquals(
Stacks.mutable.with(1, 2, 3, 4, 5), stack);
}
8. LazyIterate cartesianProduct
Sometimes it’s useful to calculate the cartesianProduct
of more than just Sets
. LazyIterate
.cartesianProduct
will take any Iterable
.
@Test
public void cartesianProduct()
{
MutableList<Integer> numbers = Lists.mutable.with(1, 2, 3);
MutableList<String> letters = Lists.mutable.with("A", "B", "C");
MutableList<Pair<String, Integer>> pairs =
LazyIterate.cartesianProduct(letters, numbers).toList();
MutableList<Pair<String, Integer>> expected =
Lists.mutable.with(
Tuples.pair("A", 1),
Tuples.pair("A", 2),
Tuples.pair("A", 3),
Tuples.pair("B", 1),
Tuples.pair("B", 2),
Tuples.pair("B", 3),
Tuples.pair("C", 1),
Tuples.pair("C", 2),
Tuples.pair("C", 3));
Assert.assertEquals(expected, pairs);
}
9. Primitive Maps updateValues
In case you want to update all of the values in a primitive Map
, now you can using updateValues
.
@Test
public void updateValues()
{
MutableIntIntMap map = IntIntMaps.mutable.empty()
.withKeyValue(1, 5)
.withKeyValue(2, 3)
.withKeyValue(3, 10);
map.updateValues((k, v) -> v + 1);
MutableIntIntMap expected = IntIntMaps.mutable.empty()
.withKeyValue(1, 6)
.withKeyValue(2, 4)
.withKeyValue(3, 11);
Assert.assertEquals(expected, map);
}
10. MutableMultimap getIfAbsentPutAll
The method getIfAbsentPutAll
on a MutableMultimap
is equivalent to getIfAbsentPut
on a MutableMap
. The difference is that with a Multimap
you can put in multiple values.
@Test
public void getIfAbsentPutAll()
{
MutableListMultimap<Integer, Integer> multimap =
Multimaps.mutable.list.with(2, 1);
ImmutableList<Integer> defaultValue =
Lists.immutable.with(1, 2, 3);
MutableList<Integer> oneValue =
multimap.getIfAbsentPutAll(1, defaultValue);
MutableList<Integer> twoValue =
multimap.getIfAbsentPutAll(2, defaultValue);
Assert.assertEquals(defaultValue, oneValue);
Assert.assertEquals(Lists.mutable.with(1), twoValue);
}
Stay Tuned!
There are still sixteen more features to cover in Eclipse Collections 10.0. I will be writing two more blogs covering all of them.
I hope you enjoy all of the new features in Eclipse Collections 10.0!
I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.