Skip to content

Factory Methods

Brian Burton edited this page Aug 24, 2023 · 2 revisions

Factory Methods

Internally JImmutable Collections uses linked lists, integer tries and balanced binary trees for the collection implementations but it strives to hide that fact from its users. There is no reason to directly create objects of the implementation classes. Your code will be cleaner and more future proof if you always create new collections using factory methods.

Each collectoin type has a class containing static factory methods to create instances of that type of collection. All interfaces and classes are in the org.javimmutable.collections package.

Interface Factory Class
IArray IArrays
IDeque IDeques
IList ILists
IListMap IListMaps
IMap IMaps
IMultiset IMultisets
ISet ISets
ISetMap ISetMaps

The static factory methods can be used to create new instances of each collection interface. For example:

import org.javimmutable.collection.ILists;

...

// create a new empty list
IList<String> es = ILists.of();

// create a new list containing all the same values as a java List
IList<String> copied = ILists.allOf(Arrays.asList("a", "b", "c"));

The second example shows how to create a new list with starting values copied from another source. Variations of the ILists.allOf() method are defined to copy values from an Iterator, or an Iterable (any java or JImmutable collection). When copying values from another source the ILists.allOf() method preserves their original order.

Equivalent constructor methods exist for creating all of the collection types. (see Collections Overview)

The factory methods for IMap that accept another IMap to copy from will detect when you are copying from a compatible map and in that case will just return the source map itself. This might happen when you want to produce a sorted map from a map passed to you and don't know the type of the map you are copying.

The IMaps.sorted() methods can create maps that sort keys based on their natural order (for keys that implement Comparable) but it can also create maps that sort keys based on a Comparator provided by the caller. When providing your own Comparator class be extremely careful to ensure that your Comparator is immutable and repeatable. The map will share your Comparator across all child instances of the map. If your Comparator is mutable and is somehow modified that could easily break the map and cause undefined behavior. Similarly if your Comparator can be affected by any outside entity that would change its comparisons of keys over time that also could break any maps that use it. If you haven't already done so be sure to read the section on Comparator in the JDK's javadoc and also the advice on how to write a well behaved Comparator in Effective Java.