Eclipse Collections by Example: FlatCollect

Donald Raab
3 min readApr 23, 2018

Learn how to flatten a collection of collections into a single collection using the flatCollect method in Eclipse Collections.

Organize a collection of collections into a single collection

What is FlatCollect?

The method flatCollect is a special form of collect, where the output of the Function provided to the method must always be some Iterable type. The purpose of flatCollect is to provide a transformation that flattens a collection of collections. This method is similar in function to flatMap in Java Streams. The primary difference is that the Function for flatCollect must return an Iterable, while the Function for flatMap must return a Stream.

Creating Intervals from Integers and flattening them to a List

FlatCollecting a List (Java 8)

@Test
public void flatCollectingAListJava8()
{
MutableList<Integer> list = mList(5, 4, 3, 2, 1);
MutableList<Integer> result = list.flatCollect(Interval::oneTo);

MutableList<Integer> expected = mList(
1, 2, 3, 4, 5,
1, 2, 3, 4,
1, 2, 3,
1, 2,
1);
Assert.assertEquals(expected, result);
}

Collection Pipelines

Martin Fowler describes the Collection Pipeline pattern here. Here is an example of flatCollect used in a collection pipeline to find all of the methods that contain “flat” in their name for a List of classes. Here I used a overloaded form of flatCollect which takes a target collection as an argument.

@Test
public void flatCollectingAListOfMethodsToASetJava8()
{
MutableList<Class<?>> list = mList(
ListIterable.class,
MutableList.class,
ImmutableList.class);
MutableSet<String> result = list
.collect(Class::getMethods)
.flatCollect(Lists.fixedSize::with, mSet())
.collect(Method::getName)
.select(each -> each.toLowerCase().contains("flat"));

MutableSet<String> expected = mSet("flatCollect");
Assert.assertEquals(expected, result);
}

The method getMethods on class returns an array, so in the Function I pass to flatCollect, I convert the array to a List. If getMethods had returned a List or some other Iterable type, I could have simply used flatCollect passing Class::getMethods.

Here’s the same example using Java 10 with Local-variable Type Inference.

@Test
public void flatCollectingAListOfMethodsToASetJava10()
{
var list = mList(
ListIterable.class,
MutableList.class,
ImmutableList.class);
var resultSet = list
.collect(Class::getMethods)
.flatCollect(Lists.fixedSize::with, mSet())
.collect(Method::getName)
.select(each -> each.toLowerCase().contains("flat"));

var expected = mSet("flatCollect");
Assert.assertEquals(expected, resultSet);
}

Symmetric Sympathy Strikes Again

While there exists a method named collectWith which is a form of collect that takes a Function2, there currently is no method named flatCollectWith which also takes a Function2. I discovered the lack of flatCollectWith (again) this week. I have submitted an issue for this feature and began working on it over the weekend. I expect to have the flatCollectWith implementation tested and completed over the next week or two.

APIs covered in the examples

  1. flatCollect— transforms elements of a source collection to a new collection by flattening collections in the source collection to a single collection
  2. mList — creates a MutableList
  3. mSet — creates a MutableSet
  4. Interval.oneTo(int) — creates an Interval starting from 1 to the specified value
  5. var — Local variable Type Inference included in Java 10 (JEP 286)

Refer to my previous blogs in the EC by Example series for examples of collect and select.

Check out this presentation to learn more about the origins, design and evolution of the Eclipse Collections API. There is also a video covering the slides that was recorded at an Eclipse Community Virtual Meet-up.

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

--

--

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.