Getting Started with Eclipse Collections — Part 3

Donald Raab
7 min readMar 28, 2023

--

Converting between Collection types using Eclipse Collections

Convert any RichIterable to a Mutable or Immutable Collection type

Getting Started with Eclipse Collections

In part 1 of this series, I explained how to download the Eclipse Collections library from Maven Central and create collections using Eclipse Collections factories. In part 2, I explained how to add items to and remove items from different collection types. In part 3, I will explain how to use converter methods to convert any RichIterable type to another Collection or Map type.

Converting between Collection types

The methods in Eclipse Collections that enable developers to convert from one RichIterable type to another, start with the prefix to. Using the to<Type> methods, the data is copied from a source collection to a target collection type, and it takes linear time (O(n)). There are also methods prefixed with as which create views, and execute in constant time (O(1)), but they will not be discussed in this blog. Calling a to<Type> method, will result in a shallow copy where only the references to the data are copied.

To Mutable Collections

In order to convert a RichIterable type to a MutableCollection type, start with the prefix to and look for the type you would like to convert to (List, Set, Bag, etc.). The converters to MutableCollection types were added before there were ImmutableCollection types in Eclipse Collections. There was a natural preference for the convenience of the shorter names, without Mutable in them.

The one exception of a to method answering a mutable type, is the method toString, which returns a familiar immutable Java type — String.

MutableCollection converters plus toArray and toString

Mutable Converter Examples

The following are examples of converting a RichIterable<Integer> to various other mutable container types in Eclipse Collections. You may recall from the other blogs in this series that RichIterable is the parent type of most Eclipse Collections container types.

@Test
public void RichIterableTo()
{
RichIterable<Integer> ri = Interval.oneTo(3);

// Lists
MutableList<Integer> list =
ri.toList();
MutableList<Integer> sortedList =
ri.toSortedList();
MutableList<Integer> sortedListBy =
ri.toSortedListBy(Object::toString);

// Sets
MutableSet<Integer> set =
ri.toSet();
MutableSortedSet<Integer> sortedSet =
ri.toSortedSet();
MutableSortedSet<Integer> sortedSetBy =
ri.toSortedSetBy(Object::toString);

// Bags
MutableBag<Integer> bag =
ri.toBag();
MutableSortedBag<Integer> sortedBag =
ri.toSortedBag();
MutableSortedBag<Integer> sortedBagBy =
ri.toSortedBagBy(Object::toString);

// Maps
MutableMap<String, Integer> map =
ri.toMap(Object::toString, Functions.identity());
MutableSortedMap<String, Integer> sortedMap =
ri.toSortedMap(Object::toString, Functions.identity());
MutableSortedMap<String, Integer> sortedMapBy =
ri.toSortedMapBy(Object::toString,
Object::toString,
Functions.identity());

// BiMap
MutableBiMap<String, Integer> biMap =
ri.toBiMap(Object::toString, Functions.identity());

// JDK Types
Object[] array = ri.toArray();
String string = ri.toString();
}

To Immutable Collections

In order to convert a RichIterable type to an ImmutableCollection type, start with the prefix to and look for the type you would like to convert to (ImmutableList, ImmutableSet, ImmutableBag, etc.). It was clear as soon as I had drawn the Immutable side of the mind map that there is currently some asymmetry with a missing method toImmutableSortedMap that should return an ImmutableSortedMap.

ImmutableCollection converters

Immutable Converter Examples

The following are examples of converting a RichIterable<Integer> to various immutable container types in Eclipse Collections.

@Test
public void RichIterableToImmutable()
{
RichIterable<Integer> ri = Interval.oneTo(3);

// Immutable Lists
ImmutableList<Integer> list =
ri.toImmutableList();
ImmutableList<Integer> sortedList =
ri.toImmutableSortedList();
ImmutableList<Integer> sortedListBy =
ri.toImmutableSortedListBy(Object::toString);

// Immutable Sets
ImmutableSet<Integer> set =
ri.toImmutableSet();
ImmutableSortedSet<Integer> sortedSet =
ri.toImmutableSortedSet();
ImmutableSortedSet<Integer> sortedSetBy =
ri.toImmutableSortedSetBy(Object::toString);

// Immutable Bags
ImmutableBag<Integer> bag =
ri.toImmutableBag();
ImmutableSortedBag<Integer> sortedBag =
ri.toImmutableSortedBag();
ImmutableSortedBag<Integer> sortedBagBy =
ri.toImmutableSortedBagBy(Object::toString);

// Immutable Map
ImmutableMap<String, Integer> map =
ri.toImmutableMap(Object::toString, Functions.identity());

// Immutable BiMap
ImmutableBiMap<String, Integer> biMap =
ri.toImmutableBiMap(Object::toString, Functions.identity());
}

Primitive Collections

The converter methods available on primitive collection types are more limited than their object counterparts. There are currently only methods prefixed with to available on the primitive Iterable types (e.g. IntIterable, LongIterable, DoubleIterable, etc.) that return Mutable<Primitive>Collection types. There are no toImmutable<Type> equivalents today.

Primitive Iterable converters plus toArray, toSortedArray and toString

Primitive Converter Examples

The following are examples of converting an IntIterable to various mutable primitive container types. The converter methods in the examples below are available across all eight primitive Iterable types.

@Test
public void IntIterableTo()
{
IntIterable ii = IntInterval.oneTo(3);

// Primitive Lists
MutableIntList list =
ii.toList();
MutableIntList sortedList =
ii.toSortedList();
MutableIntList sortedListBy =
ii.toSortedListBy(i -> -i);

// Set
MutableIntSet set =
ii.toSet();

// Bag
MutableIntBag bag =
ii.toBag();

// JDK Types
int[] array =
ii.toArray();
int[] sortedArray =
ii.toSortedArray();
String string =
ii.toString();
}

From Mutable To Immutable (Object Collections)

There is a method named toImmutable available on every MutableCollection type that knows how to convert a MutableCollection to its ImmutableCollection equivalent.

Code examples of toImmutable (Object Collections)

The following are code examples showing the toImmutable methods available across various MutableCollection and MutableMap types.

@Test
public void toImmutable()
{
// Collection
MutableCollection<Integer> collection =
Lists.mutable.with(1, 2, 3);
ImmutableCollection<Integer> immutableCollection =
collection.toImmutable();

// List
MutableList<Integer> list =
Lists.mutable.with(1, 2, 3);
ImmutableList<Integer> immutableList =
list.toImmutable();

// Sets
MutableSet<Integer> set =
Sets.mutable.with(1, 2, 3);
ImmutableSet<Integer> immutableSet =
set.toImmutable();
MutableSortedSet<Integer> sortedSet =
SortedSets.mutable.with(1, 2, 3);
ImmutableSortedSet<Integer> immutableSortedSet =
sortedSet.toImmutable();

// Bags
MutableBag<Integer> bag =
Bags.mutable.with(1, 2, 3);
ImmutableBag<Integer> immutableBag =
bag.toImmutable();
MutableSortedBag<Integer> sortedBag =
SortedBags.mutable.with(1, 2, 3);
ImmutableSortedBag<Integer> immutableSortedBag =
sortedBag.toImmutable();

// Stack
MutableStack<Integer> stack =
Stacks.mutable.with(1, 2, 3);
ImmutableStack<Integer> immutableStack =
stack.toImmutable();

// Maps
MutableMap<Integer, Integer> map =
Maps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableMap<Integer, Integer> immutableMap =
map.toImmutable();
MutableSortedMap<Integer, Integer> sortedMap =
SortedMaps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableSortedMap<Integer, Integer> immutableSortedMap =
sortedMap.toImmutable();

// BiMap
MutableBiMap<Integer, Integer> biMap =
BiMaps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableBiMap<Integer, Integer> immutableBiMap =
biMap.toImmutable();
}

From Mutable To Immutable (Primitive Collections)

There is a method named toImmutable available on every Mutable<Primitive>Collection type that knows how to convert a Mutable<Primitive>Collection to its Immutable<Primitive>Collection equivalent.

Code examples of toImmutable (Primitive Collections)

The following are code examples showing the toImmutable methods available across various Mutable<Primitive>Collection and Mutable<Primitive>Map types.

@Test
public void toImmutablePrimitive()
{
// Collection
MutableIntCollection collection =
IntLists.mutable.with(1, 2, 3);
ImmutableIntCollection immutableCollection =
collection.toImmutable();

// List
MutableIntList list =
IntLists.mutable.with(1, 2, 3);
ImmutableIntList immutableList =
list.toImmutable();

// Set
MutableIntSet set =
IntSets.mutable.with(1, 2, 3);
ImmutableIntSet immutableSet =
set.toImmutable();

// Bag
MutableIntBag bag =
IntBags.mutable.with(1, 2, 3);
ImmutableIntBag immutableBag =
bag.toImmutable();

// Stack
MutableIntStack stack =
IntStacks.mutable.with(1, 2, 3);
ImmutableIntStack immutableStack =
stack.toImmutable();

// Maps
MutableIntIntMap intIntMap =
IntIntMaps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableIntIntMap immutableIntIntMap =
intIntMap.toImmutable();
MutableIntObjectMap<Integer> intObjectMap =
IntObjectMaps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableIntObjectMap<Integer> immutableIntObjectMap =
intObjectMap.toImmutable();
MutableObjectIntMap<Integer> objectIntMap =
ObjectIntMaps.mutable.with(1, 1, 2, 2, 3, 3);
ImmutableObjectIntMap<Integer> immutableObjectIntMap =
objectIntMap.toImmutable();
}

The past, present, future of Converter Methods

I wrote a couple of blogs, two years ago, about the converter methods that were available in Eclipse Collections at the time and the ones I wanted to see in Java as well as future versions of Eclipse Collections. The blogs were inspired at the time by the introduction of the toList method to the Stream interface in Java 16.

The future I envisioned two years ago is almost complete, at least for Eclipse Collections. There is minor work to do in the Eclipse Collections object collection hierarchy. There is also an opportunity to improve symmetry by adding the toImmutable<Type> variety of methods to the primitive collections.

“Into” the Unknown!

There is a method defined on RichIterable that can be used as a catchall method to convert a type to any possible Collection type. The method is named into, and can accept any implementation of Collection as a target. The into method has been available since Eclipse Collections 8.0 was released (September 2016), and provides great interoperability with Collection containers from other Java Collections libraries. The signature of the method is as follows:

/**
* Adds all the elements in this iterable to the specific target Collection.
*
* @since 8.0
*/
<R extends Collection<T>> R into(R target);

Code examples of into on RichIterable

The following are code examples using into to convert a RichIterable implementation to a variety of specific JDK Collection types.

@Test
public void intoTheUnknown()
{
RichIterable<Integer> ri = Interval.oneTo(3);

// into JDK CopyOnWriteArrayList
CopyOnWriteArrayList<Integer> cowal =
ri.into(new CopyOnWriteArrayList<>());

// into JDK CopyOnWriteArraySet
CopyOnWriteArraySet<Integer> cowas =
ri.into(new CopyOnWriteArraySet<>());

// into JDK LinkedHashSet
LinkedHashSet<Integer> lhs =
ri.into(new LinkedHashSet<>());

// into JDK ArrayDeque
ArrayDeque<Integer> ad =
ri.into(new ArrayDeque<>());
}

Final Thoughts

Thank you for taking the time to read this blog. I hope this will be a good reference for folks to refer to in the future. I tried to be as comprehensive as possible. In the next blog in this series, I will cover in depth some of the most commonly used methods for processing information in collections.

Enjoy!

I am the creator of and a Committer for the Eclipse Collections OSS project which is managed at the Eclipse Foundation. Eclipse Collections is open for contributions.

--

--

Donald Raab

Java Champion. Creator of the Eclipse Collections OSS Java library (https://github.com/eclipse/eclipse-collections). Inspired by Smalltalk. Opinions are my own.