# As a matter of Factory — Part 3 (Method Chaining)

Learn how to add or remove elements from Java collections fluently by leveraging a few lesser known APIs in Eclipse Collections.

# Static Factories

In the first and second installment of the “As a matter of Factory” blog series, I described how to use the methods available on the *Lists*, *Sets*, and *Maps* classes to create and initialize mutable and immutable collections. For example, there are static instances of *MutableListFactory* and *ImmutableListFactory* on the Lists class, stored in the public static final variables named *mutable* and *immutable*.

MutableList<String> list =

Lists..with("1", "2", "3");ImmutableList<String> list =mutable

Lists..with("1", "2", "3");immutable

The method *with* is overloaded on the *MutableListFactory* class. One version of the *with* method takes no parameters, and returns an empty *MutableList*. The other version of the method takes a *varargs* parameter which will construct a *MutableList* with the parameters specified.

# Fluent Mutable Interfaces

The static factory methods are not the only way you can initialize a *List*, *Set*, *Bag* or *Map*. There are methods available directly on the mutable interfaces that can be used to mutate collections fluently. Each method will mutate the underlying collection by adding or removing an element and then returning the same collection.

## Equivalent Methods from JDK interfaces

- with -> add
- without -> remove
- withAll -> addAll
- withoutAll -> removeAll
- withKeyValue -> put
- withoutKey -> removeKey

# Fluently building Maps

The *with* method on *MutableListFactory* can construct a *MutableList* with a variable number of items, but the same is not true for *MutableMapFactory*. The *with* method on *MutableMapFactory* is overloaded five times.

<K, V> MutableMap<K, V> with();<K, V> MutableMap<K, V> with(K key, V value);<K, V> MutableMap<K, V> with(K key1, V value1, K key2, V value2);<K, V> MutableMap<K, V> with(K key1, V value1, K key2, V value2, K key3, V value3);<K, V> MutableMap<K, V> with(K key1, V value1, K key2, V value2, K key3, V value3, K key4, V value4);

You can only use the *with* method method to create a *MutableMap* with up to four keys and values.

`MutableMap<Integer, String> map =`

Maps.*mutable*.with(

1, **"One"**,

2, **"Two"**,

3, **"Three"**,

4, **"Four"**);

## What do you do if you need more than four keys and values?

There is a method named *withKeyValue* on *MutableMap* which can be used to fluently add an unlimited number of key and value pairs by leveraging method chaining.

## Fluently building a MutableMap using withKeyValue

MutableMap<Integer, String> numbers =

Maps..<Integer, String>empty()mutable

.withKeyValue(0,"Zero")

.withKeyValue(1,"One")

.withKeyValue(2,"Two")

.withKeyValue(3,"Three")

.withKeyValue(4,"Four")

.withKeyValue(5,"Five")

.withKeyValue(6,"Six")

.withKeyValue(7,"Seven")

.withKeyValue(8,"Eight")

.withKeyValue(9,"Nine")

.withKeyValue(10,"Ten");Assert.assertEquals("Zero", numbers.get(0));

Assert.assertEquals("One", numbers.get(1));

Assert.assertEquals("Ten", numbers.get(10));

## The withKeyValue method

`public MutableMap<K, V> withKeyValue(K key, V value)`

{

this.put(key, value);

return this;

}

## Fluently building an ImmutableMap

ImmutableMap<Integer, String> numbers =

Maps..<Integer, String>empty()mutable

.withKeyValue(0,"Zero")

.withKeyValue(1,"One")

.withKeyValue(2,"Two")

.withKeyValue(3,"Three")

.withKeyValue(4,"Four")

.withKeyValue(5,"Five")

.withKeyValue(6,"Six")

.withKeyValue(7,"Seven")

.withKeyValue(8,"Eight")

.withKeyValue(9,"Nine")

.withKeyValue(10,"Ten")

.toImmutable();Assert.assertEquals("Zero", numbers.get(0));

Assert.assertEquals("One", numbers.get(1));

Assert.assertEquals("Ten", numbers.get(10));

## Fluently building an Immutable object / primitive Map

ObjectIntMap<String> numbers =

ObjectIntMaps..<String>empty()mutable

.withKeyValue("Zero", 0)

.withKeyValue("One", 1)

.withKeyValue("Two", 2)

.withKeyValue("Three", 3)

.withKeyValue("Four", 4)

.withKeyValue("Five", 5)

.withKeyValue("Six", 6)

.withKeyValue("Seven", 7)

.withKeyValue("Eight", 8)

.withKeyValue("Nine", 9)

.withKeyValue("Ten", 10)

.toImmutable();Assert.assertEquals(0, numbers.get("Zero"));

Assert.assertEquals(1, numbers.get("One"));

Assert.assertEquals(10, numbers.get("Ten"));

## Fluently building an Immutable primitive / object Map

IntObjectMap<String> numbers =

IntObjectMaps..<String>empty()mutable

.withKeyValue(0,"Zero")

.withKeyValue(1,"One")

.withKeyValue(2,"Two")

.withKeyValue(3,"Three")

.withKeyValue(4,"Four")

.withKeyValue(5,"Five")

.withKeyValue(6,"Six")

.withKeyValue(7,"Seven")

.withKeyValue(8,"Eight")

.withKeyValue(9,"Nine")

.withKeyValue(10,"Ten")

.toImmutable();Assert.assertEquals("Zero", numbers.get(0));

Assert.assertEquals("One", numbers.get(1));

Assert.assertEquals("Ten", numbers.get(10));

## Fluently building an Immutable primitive / primitive Map

IntCharMap numbers = IntCharMaps..empty()mutable

.withKeyValue(0,'0')

.withKeyValue(1,'1')

.withKeyValue(2,'2')

.withKeyValue(3,'3')

.withKeyValue(4,'4')

.withKeyValue(5,'5')

.withKeyValue(6,'6')

.withKeyValue(7,'7')

.withKeyValue(8,'8')

.withKeyValue(9,'9')

.toImmutable();Assert.assertEquals('0', numbers.get(0));

Assert.assertEquals('1', numbers.get(1));

Assert.assertEquals('9', numbers.get(9));

# Fluently building Lists, Sets and Bags

Fluently building a *Map* using method chaining is often more useful than fluently building a *List*, *Set*, or *Bag*. Still the functionality exists if and when you need it.

## Fluently building a List

`ImmutableList<Integer> numbers =`

Lists.*mutable*.with(1)

.with(2)

.with(3)

.with(4)

.withAll(Interval.*fromTo*(5, 10))

.toImmutable();

Assert.*assertEquals*(Interval.*oneTo*(10), numbers);

Notice that I used two methods to fluently build the *MutableList*. The method *with* takes a single argument and the method *withAll* takes an *Iterable*.

## The with method

`public MutableList<T> with(T element)`

{

this.add(element);

return this;

}

## The withAll method

`public MutableList<T> withAll(Iterable<? extends T> elements)`

{

this.addAllIterable(elements);

return this;

}

## Fluently building a Set

`ImmutableSet<Integer> numbers =`

Sets.*mutable*.with(1)

.with(2)

.with(3)

.with(4)

.withAll(Interval.*fromTo*(5, 10))

.toImmutable();

Assert.*assertEquals*(Interval.*oneTo*(10).toSet(), numbers);

## Fluently building a Bag

`ImmutableBag<Integer> numbers =`

Bags.*mutable*.with(1)

.with(2)

.with(3)

.with(4)

.withAll(Interval.*fromTo*(5, 10))

.toImmutable();

Assert.*assertEquals*(Interval.*oneTo*(10).toBag(), numbers);

## Fluently building primitive Lists, Sets and Bags

ImmutableIntList list =

IntLists..with(1)mutable

.with(2)

.with(3)

.with(4)

.withAll(IntInterval.fromTo(5, 10))

.toImmutable();

Assert.assertEquals(IntInterval.oneTo(10), list);ImmutableIntSet set =

IntSets..with(1)mutable

.with(2)

.with(3)

.with(4)

.withAll(IntInterval.fromTo(5, 10))

.toImmutable();

Assert.assertEquals(IntInterval.oneTo(10).toSet(), set);ImmutableIntBag bag =

IntBags..with(1)mutable

.with(2)

.with(3)

.with(4)

.withAll(IntInterval.fromTo(5, 10))

.toImmutable();

Assert.assertEquals(IntInterval.oneTo(10).toBag(), bag);

# Using withAll in Collectors2

The *withAll* method is very useful for building Collectors which return collections. The *withAll* method is used repeatedly as a method reference in the *Collectors2* class of Eclipse Collections.

## Collectors2.toList()

`public static <T> Collector<T, ?, MutableList<T>> toList()`

{

return Collector.*of*(

Lists.*mutable*::empty,

MutableList::add,

MutableList::withAll,

*EMPTY_CHARACTERISTICS*);

}

## Collectors2.toImmutableList()

`public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList()`

{

return Collector.<T, MutableList<T>, ImmutableList<T>>*of*(

Lists.*mutable*::empty,

MutableList::add,

MutableList::withAll,

MutableList::toImmutable,

*EMPTY_CHARACTERISTICS*);

}

## Collectors2.countBy(Function)

`public static <T, K> Collector<T, ?, MutableBag<K>> countBy(Function<? super T, ? extends K> function)`

{

return Collector.*of*(

Bags.*mutable*::empty,

(bag, each) -> bag.with(*function*.valueOf(each)),

MutableBag::withAll,

*EMPTY_CHARACTERISTICS*);

}

# With or Without

We like to provide good symmetry in Eclipse Collections. If you can fluently add items to a collection, then it would make sense to be be able to remove items from a collection fluently.

## The without method on UnifiedSet

`public UnifiedSet<T> without(T element)`

{

this.remove(element);

return this;

}

Here’s an example combining some of the fluent aspects of the Eclipse Collections factories.

`ImmutableSet<String> strings =`

Sets.*mutable*.with(**"or"**, **"without"**, **"you"**)

.with(**"or"**)

.without(**"you"**)

.toImmutable();

Assert.*assertEquals*(Sets.*mutable*.with(**"or"**, **"without"**), strings);

# Final Thoughts

Hopefully you found the information and examples in this blog useful. This blog was inspired by a recent pull request submitted to Eclipse Collections. There are a lot of hidden gems inside of Eclipse Collections. I like to write about them when it becomes clear they are not so easily discovered.

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