Getting Started with Eclipse Collections — Part 3
Converting between Collection types using Eclipse Collections
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
.
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
.
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 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.