gs collections reference guide

62
GS Collections User Reference Guide Copyright © 2014 Goldman Sachs. All Rights Reserved. Version 5.0.0 (2014/03/21) Contact: [email protected]

Upload: trinhnhu

Post on 07-Jan-2017

233 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: GS Collections Reference Guide

GS Collections

User Reference Guide

Copyright © 2014 Goldman Sachs. All Rights Reserved.

Version 5.0.0 (2014/03/21)

Contact: [email protected]

Page 2: GS Collections Reference Guide

GS Collections

Page 3: GS Collections Reference Guide

GS Collections | TOC

3

Contents

About GS Collections......................................................................................................................5Getting Started With GS Collections............................................................................................7

Chapter 1: Iteration patterns.................................................................................. 9Common iteration patterns................................................................................................................................. 10

Select/Reject pattern............................................................................................................................... 10Collect pattern.........................................................................................................................................13Short-circuit patterns...............................................................................................................................15ForEach pattern.......................................................................................................................................18InjectInto pattern.....................................................................................................................................19

RichIterable......................................................................................................................................................... 20Lazy iteration.......................................................................................................................................... 21Parallel-lazy iteration.............................................................................................................................. 22RichIterable methods.............................................................................................................................. 23

Map iteration methods........................................................................................................................................31Creating iterable views of maps.............................................................................................................31Collecting entries.................................................................................................................................... 31Finding, testing and putting values........................................................................................................ 32Flipping maps......................................................................................................................................... 33

Chapter 2: Collections and containers................................................................. 35Basic collection types......................................................................................................................................... 36

ListIterable...............................................................................................................................................36SetIterable................................................................................................................................................39MapIterable............................................................................................................................................. 39Bag...........................................................................................................................................................41StackIterable............................................................................................................................................42Multimap................................................................................................................................................. 43

Primitive collections........................................................................................................................................... 44Creating and converting collections...................................................................................................................46Protecting collections..........................................................................................................................................46

Immutable collections.............................................................................................................................47Protective wrappers.................................................................................................................................48

Chapter 3: Code blocks......................................................................................... 51Predicate.............................................................................................................................................................. 53Function...............................................................................................................................................................53Procedure.............................................................................................................................................................55

Appendix A: Help...................................................................................................57Verify...................................................................................................................................................................58Q & A................................................................................................................................................................. 58GS Collections Cheat Sheet............................................................................................................................... 59

Page 4: GS Collections Reference Guide

GS Collections | TOC

4

Page 5: GS Collections Reference Guide

5

About GS Collections

A collections framework for Java based on Smalltalk patterns.

GS Collections is a library of collection-management utilities that work with the Java Collections Framework (JCF).GS Collections offers JCF-compatible implementation alternatives for List, Set and Map. It also introduces a host ofnew features including Multimaps and Bags, lazy evaluation, immutable containers, and parallel iteration utility.

GS Collections leverages the idea of internal iteration—putting collection-handling methods on the collectionclasses, a concept derived from the Smalltalk language. Internal iteration affords a more consistent and intuitiveapproach to using collections by encapsulating the details of how various iteration patterns are implemented. Hidingthis complexity lets you write more readable code with less duplication.

About this guide

This Guide is an introduction to basic GS Collections concepts and its commonly-used features. It provides a high-level survey of the GS Collections library and its capabilities. The topics covered are:

• Iteration patterns: the logic underlying GS Collections methods.• Collections & containers: the JCF compatible collection types and new containers introduced in GS Collections.• Code blocks: a function that can be passed around as data.• Utilities: factory classes, static methods, and other features of the library.

Page 6: GS Collections Reference Guide

GS Collections | About GS Collections

6

Typographical conventions

interface class method code block interface code block implementation

Page 7: GS Collections Reference Guide

7

Getting Started With GS Collections

It is recommended that first time users go through the GSC Kata. The Kata is a fun way to help you learn idiomaticGS Collections usage through coding exercises. The Kata can be found on our GitHub page: https://github.com/goldmansachs/gs-collections-kata. To run the Kata, please refer to the setup instructions found on page 24 of the Katadocument.

The Kata can be found on our GitHub page: https://github.com/goldmansachs/gs-collections-kata. To install the Kata,please refer to the Kata PDF setup instructions found on page 25 of the slideshow.

Page 8: GS Collections Reference Guide

GS Collections | Getting Started With GS Collections

8

Page 9: GS Collections Reference Guide

9

Chapter

1Iteration patterns

Topics:

• Common iteration patterns• RichIterable• Map iteration methods

GS Collections extends the Java Collections Framework with new interfacesand classes and provides additional methods. These new methods implementiteration patterns derived from the collection protocol of the Smalltalklanguage (e.g., select, reject, collect, detect).

In idiomatic Java, iteration is performed by external for and while loopsthat enclose a block of business logic to be performed on each element of acollection. This is an approach that often leads to much duplication of codestructure.

In GS Collections, business logic is reified as a code block: a class that ispassed as a parameter to an iteration method. Each implementation of aniteration method iterates over the collection, passing each element to the codeblock for processing.

The most important advantage of internal iteration patterns is that theyincrease readability by giving names to the structural iteration patterns andby reducing code duplication. Moreover, by encapsulating implementationwithin specialized collection types (e.g., list, sets, maps), iteration can beoptimized for the particular type.

Page 10: GS Collections Reference Guide

GS Collections | Iteration patterns

10

Common iteration patternsThe most commonly-used iteration patterns in GS Collections are:

• Filtering patterns:

• Select• Reject• Partition

• Transforming patterns:

• Collect• Flatten• GroupBy

• "Short-circuit" patterns:

• Detect• AnySatisfy• AllSatisfy

• Generic action patterns:

• ForEach• InjectInto

Select/Reject patternFilter a collection to create a new collection: includes select, reject, and

partition.

Methods using the Select pattern return a new collection comprising those elements from the source collection thatsatisfy some logical condition. Reject is the inverse pattern, returning a new collection of elements that do not satisfythe condition. The condition is a boolean expression in the form of single-argument code block that implements thePredicate interface.

Select pattern examples:

Pseudocode create <newCollection> for each <element> of <collection> if condition(<element>) add <element> to <newCollection>

JDK List<Integer> greaterThanFifty = new ArrayList<Integer>();for (Integer each : list){ if (each.intValue() > 50) { greaterThanFifty.add(each); }}

Page 11: GS Collections Reference Guide

GS Collections | Iteration patterns

11

Select, using an anonymous inner class as a code block:

GSC (Java 5+) MutableList<Integer> greaterThanFifty = list.select(new Predicate<Integer>() { public boolean accept(Integer each) { return each > 50; } });

Here, a Predicate is created using the Predicates factory:

GSC (Java 5+) list.select(Predicates.greaterThan(50));

GSC (Java 8) List<Integer> greaterThanFifty = list.select(each -> each > 50);

Reject pattern examples:

Pseudocode create <newCollection> for each <element> of <collection> if not condition(<element>) add <element> to <newCollection>

JDK List<Integer> notGreaterThanFifty = new ArrayList<Integer>();for (Integer each : list){ if (each <= 50) { notGreaterThanFifty.add(each); }}

GSC (Java 5+) list.reject(Predicates.greaterThan(50));

GSC (Java 8) List<Integer> notGreaterThanFifty = list.reject(each -> each > 50);

Select and Reject methods

These GS Collections methods implement the Select and Reject pattern:

select(Predicate) : RichIterable

reject(Predicate) : RichIterable

The Predicate is evaluated for each element of the collection. The selected elements are those where the Predicatereturned true (false for rejected). The selected (or rejected) elements are returned in a new collection of the sametype.

select(Predicate, targetCollection) : targetCollection

reject(Predicate, targetCollection) : targetCollection

Same as the select/reject methods with one argument, but results are added to the specified targetCollection.

selectWith(Predicate2, argument) : RichIterable

rejectWith(Predicate2, argument) : RichIterable

For each element of the collection, Predicate2 is evaluated with the element as one argument, plus one additionalargument; selected or rejected elements are returned in a new collection of the same type. See Reusing a code blockfor more information.

Page 12: GS Collections Reference Guide

GS Collections | Iteration patterns

12

selectWith(Predicate2, argument, targetCollection) : targetCollection

rejectWith(Predicate2, argument, targetCollection) : targetCollection

Same as the selectWith/rejectWith methods, but results are added to the specified targetCollection.

Partition patternCreate two collections using Select and Reject.

The Partition pattern allocates each element of a collection into one of two new collections depending on whether theelement satisfies the condition expressed by the Predicate. In effect, it combines the Select and Reject patterns. Thecollections are returned in a PartitionIterable specialized for the type of the source collection. You can retrieve theselected and rejected elements from the PartitionIterable. In this example, the list of people is partitioned into lists ofadults and children.

GSC (Java 5+) MutableList<Person> people =...PartitionMutableList<Person> partitionedFolks = people.partition( new Predicate<Person>() { public boolean accept(Person each) { return each.getAge() >= 18; } });MutableList<Person> adults = partitionedFolks.getSelected();MutableList<Person> children = partitionedFolks.getRejected();

GSC (Java 8) PartitionMutableList<Person> partitionedFolks = people.partition(person -> person.getAge() >= 18);

MutableList<Person> adults = partitionedFolks.getSelected();MutableList<Person> children = partitionedFolks.getRejected();

Partitioning methods

These GS Collections methods implement the partition pattern:

partition(Predicate) : PartitionIterable

Returns a PartitionIterable, a logical pair of containers. The first container consists of all elements that satisfythe Predicate. The second container consists of all elements that do not satisfy the Predicate. The subtypes ofPartitionIterable correspond with the subtypes of RichIterable.

partitionWith(Predicate2, argument) : PartitionIterable

For each element of the collection, Predicate2 is evaluated with the element as one argument, plus one additionalargument; partitioned elements are returned in a new collection of type PartitionIterable.

Page 13: GS Collections Reference Guide

GS Collections | Iteration patterns

13

Collect patternTransform a collection's elements, creating a new collection: includes

collect, flatCollect, and groupBy.

The Collect pattern methods return a new collection whose data elements are the results of an evaluation performedby the code block; that is, each element of the original collection is mapped to a new object, which is usually adifferent type. The code block used as the collect method's parameter implements the Function interface.

Pseudocode create <newCollection> for each <element> of <collection> <result> = transform(<element>) add <result> to <newCollection>

JDK List<Address> addresses = new ArrayList<Address>();

for (Person person : people){ addresses.add(person.getAddress());}

GSC (Java 5+) MutableList<Person> people =...;

Function<Person, Address> addressFunction = new Function<Person, Address>() { public Address valueOf(Person person) { return person.getAddress(); } };

MutableList<Address> addresses = people.collect(addressFunction);

Notice that this assumes each person in the people collection has just one address. If, instead, a person has multipleaddresses, the Function returns a list of addresses for each person (a list that has only one element if the person hasjust one address); the result is a List of Lists:

GSC (Java 5+) MutableList<Person> people =...;

Function<Person, MutableList<Address>> addressFunction = new Function<Person, MutableList<Address>>() { public MutableList<Address> valueOf(Person person) { return person.getAddresses(); } };MutableList<MutableList<Address>> addresses = people.collect(addressFunction);

GSC (Java 8) MutableList<MutableList<Address>> addresses = people.collect(person -> person.getAddresses());

//orMutableList<MutableList<Address>> addresses = people.collect(Person::getAddresses);

Other Collect-style patterns

GS Collections provides two specialized variations on the Collect pattern: Flatten and GroupBy. Like Collect, bothmethods take a single Function as a parameter.

Collect methods

These GS Collections methods implement the Collect pattern:

Page 14: GS Collections Reference Guide

GS Collections | Iteration patterns

14

collect(Function) : RichIterable

For each element of the collection, the Function is evaluated with the current element as the argument; returns anew collection of the same size and the transformed type.

collectInt(IntFunction) : IntIterable

Similar to collect, but it takes an IntFunction and returns a primitive collection. There are variants for all eightprimitives: collectBoolean, collectFloat etc.

collect(Function, targetCollection) : targetCollection

Same as collect, except that the results are added to the specified targetCollection.

collectInt(IntFunction, targetCollection) : targetCollection

Same as collectInt, except that the results are added to the specified targetCollection. There are variants for all eightprimitives.

collectIf(Predicate, Function) : RichIterable

Same as collect, except that the Predicate is first evaluated with the element as the argument to filter the collection.

collectIf(Predicate, Function,targetCollection) : targetCollection

Same as collectIf, except that the results are added to the specified targetCollection.

collectWith(Predicate2, argument2) : RichIterable

Same as collect, but the Predicate2 is evaluated with the element as one argument, plus one additional argument;returns a new collection of the same size and the transformed type.

collectWith(Predicate2, argument2,targetCollection) : targetCollection

Same as collectWith, except that the results are added to a specified targetCollection. (On all RichIterables sinceversion 1.0)

Flatten patternCreate a single, linear collection from selected values of a collection's

elements.

The Flatten pattern is a specialized form of the the Collect pattern. It returns a single-level, or "flattened," collectionof attribute values from a source collection's elements.

flatCollect(Function) : RichIterable

Applies the Function to each element. The Function must return an Iterable type. Returns the intermediate Iterablesin a single, flattened collection.

Page 15: GS Collections Reference Guide

GS Collections | Iteration patterns

15

Given a list of people (as in the collect method example), here is how flatCollect could be used to create a flat listfrom the address fields of the person objects in that list, using the same Function (addressFunction):

Pseudocode create <newCollection> for each <element> of <collection> <results> = transform(<element>) Add all <results> to <newCollection>

JDK List<Address> addresses = new ArrayList<Address>();for (Person person : people){ addresses.addAll(person.getAddresses());}

GSC (Java 5+) MutableList<Address> addresses = people.flatCollect(addressFunction);

Note the flatCollect method's similarity to a collect method having the same signature: each method's Functionparameter maps to an Iterable type. This is optional for collect, but required of flatCollect. Both methods return anew collection. The difference is that collect in this form creates a collection of collections from a simple List, Set orBag, while flatCollect performs a different (and in this instance, somewhat more useful) action, returning a flat list ofaddresses.

GSC (Java 8) MutableList<Address> flatAddress = people.flatCollect(person -> person.getAddress());MutableList<Address> flatAddress = people.flatCollect(Person::getAddress);

GroupBy patternCreate a Multimap from a collection by grouping on a selected or

generated key value.

The GroupBy pattern gathers the elements on the collection into a map-like container called a Multimap, whichassociates multiple values for each key. The Function is applied to each element and the result is used as the key intothe Multimap where the element should appear as the value.

groupBy(Function) : Multimap

Group the elements into a new Multimap; uses the Function to get the key for each element.

groupBy(Function, targetMultimap) : targetMultimap

Same as groupBy except that results are added to the specified targetMultimap.

groupByEach(Function) : Multimap

Same as groupBy except that the Function transforms each value into multiple keys, returning a new Multimapcontaining all the key/value pairs.

Short-circuit patternsMethods that control processing by testing a collection for a logical

condition: includes detect, anySatisfy, and allSatisfy.

The "short-circuit" patterns - Detect, AnySatisfy and AllSatisfy - are so called because they describe methods thatcease execution when a specific condition is met. With each iteration, the Predicate is evaluated. If the evaluationresolves as a specified boolean (true/false) value, then iteration halts and returns the appropriate value.

Page 16: GS Collections Reference Guide

GS Collections | Iteration patterns

16

Detect patternFinds and returns the first element that satisfies a given logical

expression.

Detect returns the first element that satisfies a Predicate. If every element in the collection is tested and the Predicatenever returns true, then the method returns null.

Pseudocode for each <element> of <collection> if condition(<element>) return <element>

JDK for (int i = 0; i < list.size(); i++){ Integer v = list.get(i); if (v.intValue() > 50) { return v; } return null;}

GSC (Java 5+) list.detect(Predicates.greaterThan(50));

GSC (Java 8) list.detect(each -> each > 50);

Detect methods

detect(Predicate) : element

Return the first element which satisfies the Predicate or null if no element satisfies the Predicate.

detectIfNone(Predicate, Function0) : element (or Function0 result)

Same as detect, but if no element causes Predicate to evaluate as true, return the result of evaluating Function0.

detectWith(Predicate2, parameter) : element

Returns the first element that evaluates as true for the specified Predicate2 and parameter, or null if none evaluateas true. See Reusing a code block for more information.

detectWithIfNone(Predicate2, parameter, Function0) : element (or Function0 result)

Same as detectWith, but if no element causes Predicate2 to evaluate as true, return the result of evaluatingFunction0.

Page 17: GS Collections Reference Guide

GS Collections | Iteration patterns

17

AnySatisfy patternDetermine if any collection element satisfies a given logical expression.

The AnySatisfy method determines whether any element satisfies the Predicate. It applies the Predicate to eachelement. If the Predicate ever returns true, execution halts and the method returns true immediately. Otherwise, everyelement is checked and the method returns false.

Pseudocode for each <element> of <collection> if condition(<element>) return true otherwise return false

JDK for (int i = 0; i < list.size(); i++){ Integer v = list.get(i); if (v.intValue() > 50) { return true; }}return false;

GSC (Java 5+) return list.anySatisfy(Predicates.greaterThan(50));

GSC (Java 8) return list.anySatisfy(num -> num > 50);

AnySatisfy methods

anySatisfy(Predicate) : boolean

Return true if the Predicate returns true for any element of the collection. Otherwise (or if the collection is empty),return false.

anySatisfyWith(Predicate2, parameter) : boolean

Return true if the Predicate2 returns true for any element of the collection. Otherwise (or if the collection is empty),return false.

Page 18: GS Collections Reference Guide

GS Collections | Iteration patterns

18

AllSatisfy patternDetermine if all collection elements satisfy a given logical expression.

The AllSatisfy method determines whether all elements satisfy the Predicate. It applies the Predicate to each element.If the Predicate ever returns false, execution halts and the method returns false immediately. Otherwise, everyelement is checked and the method returns true.

Pseudocodefor each <element> of <collection> if not condition(<element>) return false otherwise return true

JDK for (int i = 0; i < list.size(); i++){ Integer v = list.get(i); if (v.intValue() <= 50) { return false; }}return true;

GSC (Java 5+) return list.allSatisfy(Predicates.greaterThan(50));

GSC (Java 8) return list.allSatisfy(each -> each > 50);

NoneSatisfy is similar to AllSatisfy, but negates the Predicate. It returns true only if no element satisfies the Predicate.If the container is empty it also returns true.

AllSatisfy methods

allSatisfy(Predicate) : boolean

Return true if the Predicate returns true for all elements of the collection. Otherwise (or if the collection is empty),return false.

allSatisfyWith(Predicate2, parameter) : boolean

Return true if the Predicate2 returns true for all elements of the collection. Otherwise (or if the collection is empty),return false.

noneSatisfy(Predicate) : boolean

Return true if the Predicate returns false for all elements of the collection or if the collection is empty. Otherwise,return false.

noneSatisfyWith(Predicate2, parameter) : boolean

Return true if the Predicate2 returns false for all elements of the collection or if the collection is empty. Otherwise,return false.

ForEach patternPerform a calculation on each element of the current collection.

The ForEach pattern defines the most basic iteration operation that can be used with all collection types. Unlike theother patterns discussed in this topic, the ForEach pattern prescribes methods that operate on each element of thecalling collection object, with no value returned by the method itself.

Page 19: GS Collections Reference Guide

GS Collections | Iteration patterns

19

In GS Collections, the forEach method offers the most straightforward replacement for the Java for loop. It executesthe code in a Procedure on each element. You can use these methods to perform some action using the values of thesource collection - for example, to print a value or to call another method on each element.

Pseudocode for each <element> of <collection> evaluate(<element>)

JDK for (int i = 0; i < list.size(); i++){ this.doSomething(list.get(i));}

GSC (Java 5+) list.forEach(new Procedure(){ public void value(Object each) { doSomething(each); }});

GSC (Java 8) Procedure run = each -> doSomething(each); list.forEach(run);

ForEach methods

forEach(Procedure) : void

For each element, the code block is evaluated with the element as the argument.

forEachIf(Predicate, Procedure) : void

For each element that satisfies the Predicate, executes the Procedure on that element.

forEach(fromIndex, toindex, Procedure) : void

Iterates over the section of a ListIterable covered by the specified indexes (inclusive).

forEachWith(Procedure2, parameter) : void

For each element of the collection, the code block is evaluated with the element as the first argument, and thespecified parameter as the second argument.

forEachWithIndex(ObjectIntProcedure) : void

Iterates over a collection passing each element and the current relative int index to the specified instance ofObjectIntProcedure.

forEachWithIndex(fromIndex, toIndex, ObjectIntProcedure) : void

Iterates over the section of the list covered by the specified indexes (inclusive).

InjectInto patternCalculate and maintain a running value during iteration; use each

evaluated result as an argument in the next iteration.

The InjectInto pattern is used to carry a computed result from one iteration as input to the next. In this pattern, theinjectInto method takes an initial injected value as a parameter. This value is used as the first argument to a two-argument code block; the current element (for each iteration of the collection) is taken as the second argument.

Page 20: GS Collections Reference Guide

GS Collections | Iteration patterns

20

For each iteration, the code block's evaluation result is passed to the next iteration as the first argument (the injectedvalue) of the code block, with the (new) current element as the second argument. The injectInto() method returns thecode block's cumulative result upon the final iteration.

Pseudocode set <result> to <initialvalue> for each <element> of <collection> <result> = apply(<result>, <element>) return <result>

JDK List<Integer> list = Lists.mutable.of(1, 2);int result = 3;for (int i = 0; i < list.size(); i++){ Integer v = list.get(i); result = result + v.intValue();}

GSC (Java 5+) Lists.mutable.of(1, 2).injectInto(3, AddFunction.INTEGER);

GSC (Java 8) Lists.mutable.of(1, 2).injectInto(3, (result, each) -> Integer.valueOf(result + each));

InjectInto methods

injectInto(injectedValue, Function2) : (final result)

Return the final result of all evaluations using as the arguments each element of the collection, and the result of theprevious iteration's evaluation.

injectInto(floatValue, FloatObjectToFloatFunction) : float

Return the final result of all evaluations using as the arguments each element of the collection, and the result of theprevious iteration's evaluation. The injected value and result are both primitive floats.

injectInto(intValue, IntObjectToIntFunction) : int

Return the final result of all evaluations using as the arguments each element of the collection, and the result of theprevious iteration's evaluation. The injected value and final result are both primitive ints.

injectInto(longValue, LongObjectToLongFunction) : long

Return the final result of all evaluations using as the arguments each element of the collection, and the result of theprevious iteration's evaluation. The injected value and result are both primitive longs.

injectInto(doubleValue, DoubleObjectToDoubleFunction) : double

Return the final result of all evaluations using as the arguments each element of the collection, and the result of theprevious iteration's evaluation. The injected value and result are both primitive doubles.

RichIterableRichIterable is the most important interface in GS Collections. It provides the blueprint for all non-mutating iterationpatterns. It represents an object made up of elements that can be individually and consecutively viewed or evaluated(an iterable), and it prescribes the actions that can be performed with each evaluation (the patterns). The mostcommonly used implementations include FastList and UnifiedSet.

RichIterable is extended by ListIterable, SetIterable, Bag, StackIterable, and MapIterable. A MapIterable of keysand values is also a RichIterable of values.

RichIterable is also extended by MutableCollection, and indirectly by MutableList and MutableSet (whichalso extend the mutable Java Collection types List and Set). Another subinterface defines a non-JDK container,

Page 21: GS Collections Reference Guide

GS Collections | Iteration patterns

21

MutableBag (or multiset); yet another, ImmutableCollection , delineates the immutable forms of these GSCollections containers. These latter two interfaces are detailed in the Collections and containers topic.

The subinterface LazyIterable for the most part replicates RichIterable, but overrides some specific collection-returning methods - collect, collectIf, select, reject, and flatCollect - so that they delay their actual execution untilthe returned collection is needed, a technique called "lazy iteration."

Lazy iterationDeferring evaluation until necessary.

Lazy iteration is an optimization pattern in which an iteration method is invoked, but its actual execution is deferreduntil its action or return values are required by another, subsequent method. In practical terms, the objective istypically to forestall unnecessary processing, memory use, and temporary-object creation unless and until they areneeded. Lazy iteration is implemented as an adapter on the current RichIterable collection by this method:

richIterable.asLazy() Returns a deferred-evaluation iterable. (Note the listbelow of other GS Collections methods that return lazyIterables.)

In a way, lazy iteration is a companion to the short-circuit iteration pattern, in which iteration ceases as soon themethod's purpose is achieved. In the last line of the example below, the anySatisfy method quits execution whenit detects the "address2" element in the addresses list created by collect. The third element ("address 3") is neverexamined by anySatisfy—although it was present in addresses.

GSC (Java 5+) Person person1 = new Person(address1); Person person2 = new Person(address2); Person person3 = new Person(address3); MutableList<Person> people = FastList.newListWith(person1, person2, person3); MutableList<MutableList<Address>> addresses = people.collect(addressFunction); Assert.assertTrue(addresses.anySatisfy(Predicates.equal(address2)));

One excess element out of three may be trivial, but if people were to be a very long list (or a stream), anySatisfy willstill have to wait for the collect method to finish aggregating an equally-large temporary collection—one that willhave only its first two elements inspected. By applying a lazy-iteration adapter to people, the collect iteration defersto that of anySatisfy: only the elements anySatisfy requires are "collected."

GSC (Java 5+) MutableList<Person> people = FastList.newListWith(person1, person2, person3); LazyIterable<Person> lazyPeople = people.asLazy(); LazyIterable<Address> addresses = lazyPeople.collect(addressFunction); Assert.assertTrue(addresses.anySatisfy(Predicates.equal(address2)));

This example demonstrates lazy iteration using both Java 8 lambdas and method references:

GSC (Java 8) LazyIterable<Person> lazyPeople = people.asLazy();

LazyIterable<Address> addresses = lazyPeople.flatCollect(person -> person.getAddress()); //orLazyIterable<Address> addresses = lazyPeople.flatCollect(Person::getAddress);

Page 22: GS Collections Reference Guide

GS Collections | Iteration patterns

22

In this example, the values in a Multimap are flattened and sorted, the results processed and sent to a stream byforEach.

GSC (Java 5+) myMultimap.multiValuesView() // returns a lazy iterable by default .select(ITERABLE_SIZE_AT_THRESHOLD) // invoked but deferred .select(ITERABLE_SIZE_AT_THRESHOLD) // invoked but deferred .asSortedList(DESCENDING_ITERABLE_SIZE) // as "select" evaluates, // sort elements in a non-lazy // sorted list. .asLazy() // restores the lazy adapter .collect(ITERABLE_TO_FORMATTED_STRING) // invoked but deferred .collect(ITERABLE_TO_FORMATTED_STRING) // invoked but deferred .forEach(Procedures.println(System.out));// as "collect" evaluates, // send results to stream.

Because a lazy iterable adapter is used, the Collect evaluation occurs only as the ForEach evaluation calls for it;there is no intervening collection. Without the lazy adapter, collect would execute in full, then return a collection toforEach.

Finally, note these GS Collections methods that implicitly return a lazy-iterable type.

MutableMap interface and its implementations

valuesView() : RichIterable An unmodifiable view of the map's values.

keysView() : RichIterable An unmodifiable view of the map's keyset.

keyValuesView() : RichIterable An unmodifiable view of the map's entryset.

Multimap interface and its implementations

keyMultiValuePairsView() : RichIterable An unmodifiable view of key and multi-value pairs.

keysView() : RichIterable An unmodifiable view of unique keys.

keyValuePairsView() : RichIterable An unmodifiable view of key/value pairs.

multiValuesView() : RichIterable An unmodifiable view of each key's values, without thekey.

Parallel-lazy iterationAn API that combines parallel iteration with lazy evaluation.

Parallel-eager utility is available through the ParallelIterate utility class. Serial-lazy evaluation is available throughLazyIterable, the view returned by RichIterable.asLazy(). The ParallelIterable interface defines a view whereiteration is both parallel and lazy. Sub-interfaces of ParallelIterable are returned from the various implementations ofasParallel( ExecutorService executorService, int batchSize ). The ParallelIterable API is new in 5.0 and consideredexperimental, as indicated by the @Beta annotation. API tagged as @Beta may be altered in ways that are not

Page 23: GS Collections Reference Guide

GS Collections | Iteration patterns

23

backward-compatible, even in minor versions of GS Collections. The method asParallel is not on interfaces likeRichIterable in version 5.0, but rather on a few supported collections, including FastList and UnifiedSet.

FastList integers = FastList.newListWith(1, 2, 3, 4, 5, 6, 7, 8, 9);

ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());int batchSize = 2;ParallelListIterable parallelListIterable = integers.asParallel(threadPool, batchSize);// deferred evaluationParallelListIterable evenNumbers = parallelListIterable.select(each -> each % 2 == 0);// deferred evaluationParallelListIterable evenStrings = evenNumbers.collect(Object::toString);// forced evaluationMutableList strings = evenStrings.toList();threadPool.shutdown();Assert.assertEquals(FastList.newListWith("2", "4", "6", "8"), strings);

In this code example, the calls to select and collect are lazy, as indicated by the fact that they return subclasses ofParallelIterable. The call to toList() forces evaluation.

The two parameters to asParallel(ExecutorService executorService, int batchSize) are used to configure parallelism.

executorService This code example set up a thread pool with one thread per core, which is appropriatefor CPU bound tasks. A thread pool used for IO bound tasks should be infinite orshould have one thread per IO-bound resource, for example, one thread per databaseconnection. It often makes sense to share thread pools between multiple calls toasParallel.

batchSize The batch size determines the number of elements from the backing collection(FastList or UnifiedSet) that get processed by each task submitted to the thread pool.Appropriate batch sizes for CPU-bound tasks are usually larger, in the 10,000 to100,000 range.

Performance

As with lazy evaluation, there is no guarantee that using parallel-lazy evaluation will yield better performance thansimple serial-eager evaluation. Performance testing is required, using an appropriate thread pool and trying variousbatch sizes.

Cancelability

It's possible to cancel a parallel-lazy computation in progress. It requires a thread pool that can be shut down, whichmeans it usually won't be a thread pool shared between multiple computations. Cancelling also requires a runnablethread with access to the thread pool. Building on the previous example, we just need to change evenStrings.toList()to execute in a background thread. Then the main thread could call threadPool.shutdownNow() which would causetoList() to terminate relatively quickly by throwing an exception. Shutting down the thread pool won't stop anybatches in progress. However, no new batches will be started.

RichIterable methodsThese methods are available on all implementations of RichIterable.

Page 24: GS Collections Reference Guide

GS Collections | Iteration patterns

24

Building stringsMethods that convert collection elements to a string that can be

appended to a stream or buffer.

The makeString method returns a representation of the calling RichIterable collection as a String object. Elementsare converted to strings as they would be by String.valueOf(Object). You can specify start and end strings asdelimiters (the default is an empty string for both) and the separator string for the between-values delimiter (defaultsto comma and space).

makeString(startString, separatorString,endString) : String

Returns a string representation of the calling collection thatis a list of elements in the order they are returned by theiterator, enclosed in the startString and endString. Elementsare delimited by the separatorString.

makeString(separatorString) : String Same result with no starting and ending strings.

makeString() : String Same result with the default delimiter ", " (comma space) andno starting and ending strings.

GSC (Java 5+) MutableList<Integer> list = FastList.newListWith(1, 2, 3); String myDelim = list.makeString("[", "/", "]"); // "[1/2/3]" String mySeper = list.makeString("/"); // "1/2/3" String defaultString = list.makeString(); //"1, 2, 3"

The appendString method uses forms similar to makeString, but the string representation of the collection is writtento a Java Appendable object, such as a PrintStream, StringBuilder or StringBuffer; the method itself is void.

appendString(Appendable, startString, separatorString,endString) : void

Appends a string representation of this collectiononto the given Appendable using the specifiedstart, end, and separator strings

appendString(Appendable, separatorString) : void Appends with specified separator, but no startingor ending strings.

appendString(Appendable) : void Appends with the default delimiter ", " (commaspace) and no starting and ending strings.

GSC (Java 5+) MutableList<Integer> list = FastList.newListWith(1, 2, 3); Appendable myStringBuilder = new StringBuilder(); list.appendString(myStringBuilder, "[", "/", "]"); //"[1/2/3]");

Counting elementsGet the total number of elements that satisfy a condition.

The count and countWith methods calculate the number of collection elements that satisfy a given predicate. ThecountWith method takes a second parameter that is used as an additional argument in evaluating the current element.

count(Predicate) : int

Returns the number of elements that satisfy the Predicate. For example:

GSC (Java 5+) return people.count(new Predicate<Person>() { public boolean value(Person person) { return person.getAddress().getState().getName().equals("New York"); } });

Page 25: GS Collections Reference Guide

GS Collections | Iteration patterns

25

Here is a Java 8 lambda example:

GSC (Java 8) return people.count(person -> person.getAddress().getState().getName().equals("New York"));

countWith(Predicate2, parameter) : int

Returns the number of elements that satisfy the Predicate2. The second parameter to countWith is passed as thesecond parameter to the Predicate2.

GSC (Java 5+) return lastNames.countWith(Predicates2.equal(), "Smith");

Use these methods to get the total number of collection items or to determine whether the collection is empty.

size() : int Returns the number of items in the collection.

isEmpty() : boolean Returns true if this iterable has zero items.

notEmpty() : boolean Returns true if this iterable has greater than zero items.

Finding elementsLocate elements by iteration position or highest/lowest value.

The getFirst and getLast methods return the first and last elements, respectively of a RichIterable collection. In thecase of a List, these are the elements at the first and last index. For all any other collections, getFirst and getLastreturn the first and last elements that would be returned by an iterator. Note that the first or last element of a hash-based Set could be any element, because element order in a hashed structure is not defined. Both methods return nullif the collection is empty. If null is a valid element, use the isEmpty method to determine if the container is in factempty.

getFirst() : elementReturns the first element of an iterable collection.

getLast() : elementReturns the last element of an iterable collection.

The min and max methods, without parameters, return an element from an iterable based on its natural order, that is,by calling the compareTo() method on each element.

max() : element Returns the maximum value based on the natural ordering.

min() : element Returns the minimum value based on the natural ordering.

GSC (Java 5+) RichIterable<Integer> iterable = FastList.newListWith(5, 4, 8, 9, 1); Assert.assertEquals(Integer.valueOf(9), iterable.max()); Assert.assertEquals(Integer.valueOf(1), iterable.min());

If any element in the iterable is not Comparable, then a ClassCastException is thrown.

GSC (Java 5+) RichIterable<Object> iterable = FastList.newListWith(5, 4, 8, 9, 1, new Foo()); iterable.max(); // throws ClassCastException

The min and max methods each have an overload that takes a Comparator that determines the natural order.

max(Comparator) : element Returns the maximum element out of this collection based on the comparator.

min(Comparator) : element Returns the minimum element out of this collection based on the comparator.

Page 26: GS Collections Reference Guide

GS Collections | Iteration patterns

26

GSC (Java 5+) public class SillyWalk { public final int wiggles;

public SillyWalk(int wiggles) { this.wiggles = wiggles; }}

private static final Comparator<SillyWalk> SILLY_WALK_COMPARATOR = new Comparator<SillyWalk>() { public int compare(SillyWalk o1, SillyWalk o2) { return o1.wiggles - o2.wiggles; } };

SillyWalk sillyWalk2 = new SillyWalk(2); SillyWalk sillyWalk3 = new SillyWalk(3);

RichIterable<SillyWalk> walks = FastList.newListWith(sillyWalk2, sillyWalk3);

Assert.assertEquals(sillyWalk3,walks.max(SILLY_WALK_COMPARATOR)); Assert.assertEquals(sillyWalk2,walks.min(SILLY_WALK_COMPARATOR));

The related methods minBy and maxBy take a Function and return the minimum or maximum element in theRichIterable based on the natural order of the attribute returned by the Function.

maxBy(Function) : element Returns the maximum element out of this collection based on the result ofapplying the Function to each element.

minBy(Function) : element Returns the minimum element out of this collection based on the result ofapplying the Function to each element.

Here, we find the youngest person (the minimum person by age).

GSC (Java 5+) Person alice = new Person("Alice", 40); Person bob = new Person("Bob", 30); Person charlie = new Person("Charlie", 50);

MutableList<Person> people = FastList.newListWith(alice, bob, charlie);

Assert.assertEquals(bob, people.minBy(Person.TO_AGE));

In the code example we already had a Function, so calling minBy was more concise than calling min(). These twoforms are equivalent though.

GSC (Java 5+) people.minBy(Person.TO_AGE); people.min(Comparators.byFunction(Person.TO_AGE));

Aggregating elementsMethods that create maps of aggregated values by grouping them on a

calculated key.

aggregateBy groups the elements in the RichIterable by the Function. Then all the elements that map to the samekey are aggregated together using the Function2. The third parameter, a Function0, creates the initial value in eachaggregation. Aggregate results are allowed to be immutable as they will be replaced in the map.

aggregateBy is conceptually analogous to calling a groupBy method on a RichIterable to create a Multimap,andthen calling injectInto on each collection of the Multimap values to create a MapIterable.

aggregateInPlaceBy is similar to aggregateBy, but it mutates values in the output map instead of replacing them.Thus in this case, the aggregate results must be mutable.

Page 27: GS Collections Reference Guide

GS Collections | Iteration patterns

27

aggregateBy(Function, Function0, Function2) : MapIterable Returns a MapIterable bygrouping results by keyssupplied by evaluating aFunction.

GSC (Java 5+) Function0<Integer> factory = new Function0<Integer>() { public Integer value() { return Integer.valueOf(0); } };

Function2<Integer, Integer, Integer> sumAggregator = new Function2<Integer, Integer, Integer>() { public Integer value(Integer aggregate, Integer value) { return aggregate + value; } };

Function<Integer, Integer> groupBy = new Function<Integer, Integer>() { public Integer valueOf(Integer integer) { return integer % 2; } }; FastList<Integer> integers = FastList.newListWith(1, 1, 1, 2, 2, 3); MutableMap<Integer, Integer> aggregation = integers.aggregateBy(groupBy, factory, sumAggregator); Assert.assertEquals(4, aggregation.get(0).intValue()); Assert.assertEquals(6, aggregation.get(1).intValue());

GSC (Java 8) FastList<Integer> integers = FastList.newListWith(1, 1, 1, 2, 2, 3);MutableMap<Integer, Integer> aggregation =integers.aggregateBy( integer -> integer % 2, () -> 0, Integer::sum);Assert.assertEquals(4, aggregation.get(0).intValue());Assert.assertEquals(6, aggregation.get(1).intValue());

Page 28: GS Collections Reference Guide

GS Collections | Iteration patterns

28

aggregateInPlaceBy(Function, Function0, Function2) : MapIterable Same result with no startingand ending strings.

GSC (Java 5+) Function0<AtomicInteger> factory = new Function0<AtomicInteger>() { public AtomicInteger value() { return new AtomicInteger(0); } }; Procedure2<AtomicInteger, Integer> sumAggregator = new Procedure2<AtomicInteger, Integer>() { public void value(AtomicInteger aggregate, Integer value) { aggregate.addAndGet(value); } };

Function<Integer, Integer> groupBy = new Function<Integer, Integer>() { public Integer valueOf(Integer integer) { return integer % 2; } }; FastList<Integer> integers = FastList.newListWith(1, 1, 1, 2, 2, 3); MutableMap<Integer, AtomicInteger> aggregation = integers.aggregateInPlaceBy(groupBy, factory, sumAggregator); Assert.assertEquals(4, aggregation.get(0).intValue()); Assert.assertEquals(6, aggregation.get(1).intValue());

GSC (Java 8) FastList<Integer> integers = FastList.newListWith(1, 1, 1, 2, 2, 3);MutableMap<Integer, AtomicInteger> aggregation =integers.aggregateInPlaceBy( integer -> integer % 2, () -> new AtomicInteger(0), AtomicInteger::addAndGet)Assert.assertEquals(4, aggregation.get(0).intValue());Assert.assertEquals(6, aggregation.get(1).intValue());

Using chunk and zip to create collectionsGrouping and pairing elements of one or more collections.

The chunk method can be used to gather the elements of a collection into chunks; that is, it creates a collection madeup of collections of a specified fixed size (an integer). If the size doesn't divide evenly into the total of collectionelements, then the final chunk is smaller.

chunk(size) : RichIterable

Returns a new collection with the source collection's elements grouped in "chunks," with size elements in eachchunk, and the last chunk containing the remaining elements, if any.

GSC (Java 5+) MutableList<Integer> list = FastList.newListWith(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); RichIterable<RichIterable<Integer>> chunks = list.chunk(4);

System.out.println(chunks);

This example prints out:

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]

The zip method pairs up the elements of one RichIterable with those of second. If one of the two collections hasmore elements than the other, those remaining elements are dropped. The zipWithIndex method is a special case ofzip that pairs the elements in a collection with their index positions.

Page 29: GS Collections Reference Guide

GS Collections | Iteration patterns

29

zip(RichIterable) : RichIterable

Returns a new RichIterable by combining, into pairs, corresponding elements from the calling RichIterablecollection and the RichIterable collection named in the parameter. If one of the two collections is longer, itsremaining elements are ignored..

GSC (Java 5+) MutableList<String> list1 = FastList.newListWith("One", "Two", "Three", "Truncated"); MutableList<String> list2 = FastList.newListWith("Four", "Five", "Six"); MutableList<Pair<String, String>> pairs = list1.zip(list2); System.out.println(pairs);

This example prints out:

[One:Four, Two:Five, Three:Six]

zipWithIndex() : RichIterable

Returns a new RichIterable consisting of the calling collection's elements, each paired with its index (beginningwith index 0).

GSC (Java 5+) MutableList<String> list = FastList.newListWith("One", "Two", "Three"); MutableList<Pair<String, Integer>> pairs = list.zipWithIndex(); System.out.println(pairs);

This example prints out:

[One:0, Two:1, Three:2]

Performance optimized methods: reusing two-argument code blocksUsing selectWith, rejectWith, and collectWith inside other iteration

patterns (or loops) where code blocks can be created outside of the outeriteration patterns or made static.

The collection-returning iteration methods—collect, select, and reject—each take a single parameter: a codeblock that itself takes a single argument. These patterns have alternate forms, methods named collectWith,selectWith, and rejectWith respectively. The same is true of the boolean-returning "short-circuit" methods, detect,anySatisfy, allSatisfy, and noneSatisfy; each has a counterpart having the suffix "With." All of these are available onRichIterable and its subinterfaces.

In each case, the "...With" form of the method takes two parameters:

• The first method parameter is a code block that itself takes two arguments; the first argument of the code block isthe current element with each iteration.

• The second method parameter is an object that is then passed to the code block as its second argument.

selectWith(Predicate2, argument) : RichIterable

rejectWith(Predicate2, argument) : RichIterable

For each element of the collection, Predicate2 is evaluated with the element as one argument, plus one additionalargument; selected or rejected elements are returned in a new collection of the same type.

collectWith(Predicate2, argument) : RichIterable

Same as the collect method, but two arguments are passed to the code block; returns a new collection of the sametype and size.

Page 30: GS Collections Reference Guide

GS Collections | Iteration patterns

30

These " ...With" forms accomplish exactly the same actions as their basic counterparts. Although slightly moreverbose, they allow for a specific performance optimization, that is re-use of the code block with different arguments.Here is an example of select that finds the adults in a list of people. First, the JDK version, and then rewritten in GSCollections form:

JDK List<Person> people =...; List<Person> adults = new ArrayList<Person>(); for (Person person : people) { if (person.getAge() >= 18) { adults.add(person); } }

GSC (Java 5+) MutableList<Person> people =...; MutableList<Person> adults = people.select( new Predicate<Person>() { public boolean accept(Person each) { return each.getAge() >= 18; } });

Here's the same algorithm, again in GS Collections, this time using selectWith():

GSC (Java 5+) MutableList<Person> people =...; MutableList<Person> adults = people.selectWith( new Predicate2<Person, Integer>() { @Override public boolean accept(Person eachPerson, Integer age) { return eachPerson.getAge() > age; } }, 18);

In this single instance, there is no reason to write it out this longer way; the extra generality - making age the secondargument to the Predicate2 - is unnecessary.

It does make sense, however, if you wanted to filter on multiple ages: you could hold onto and re-use the Predicate2,thereby creating less garbage.

GSC (Java 5+) MutableList<Person> people =...; Predicate2<Person, Integer> agePredicate = new Predicate2<Person, Integer>() { @Override public boolean accept(Person eachPerson, Integer age) { return eachPerson.getAge() > age; } }; MutableList<Person> drivers = people.selectWith(agePredicate, 17); MutableList<Person> voters = people.selectWith(agePredicate, 18); MutableList<Person> drinkers = people.selectWith(agePredicate, 21);

collectWith, selectWith, and rejectWith work well with method references.

GSC (Java 8) MutableList<Person> drivers = people.selectWith(Person::isAgeGreaterThan, 17);MutableList<Person> voters = people.selectWith(Person:: isAgeGreaterThan, 18);MutableList<Person> drinkers = people.selectWith(Person:: isAgeGreaterThan, 21);

This style encourages adding more behavior to the classes held in the containers. This style works with any "...With"method in Java 8 or higher.

Page 31: GS Collections Reference Guide

GS Collections | Iteration patterns

31

Map iteration methodsMethods for iterating over Maps and Multimaps.

The MapIterable and Multimap interfaces are associative arrays, meaning they contain key-value pairs. All of thekeys in a Map are unique; a Multimap can have multiple values associated with each key.

The Multimap interface does not extend MapIterable. Multimap has a number of subinterfaces, such asListMultimap, SetMultimap, and BagMultimap, each with custom behavior for how to handle the collection ofvalues associated with each key.

Creating iterable views of mapsWrapper classes that return an iterable view of a map; ForEach patterns

for Map containers.

These three methods each return an unmodifiable RichIterable view of a Map. They are essentially wrappers over themodifiable, non-lazy objects returned by the corresponding Java Collections Framework methods.

valuesView() : RichIterable (Maps and Multimaps) Returns an unmodifiable RichIterablewrapper over the values of the Map.

keysView() : RichIterable (Maps and Multimaps) Returns an unmodifiable RichIterablewrapper over the keySet of the Map.

keyValuesView() : RichIterable (Maps only) Returns an unmodifiable lazy iterable of key/valuepairs.

ForEach Iteration

These three methods call a code block for each element on a Map (all return void).

forEachKey(Procedure) : void Calls the Procedure on each key of the Map.

forEachValue(Procedure) : void Calls the Procedure on each value of the Map.

forEachKeyValue(Procedure2) : void Calls the Procedure on each key-value pair of the Map.

Collecting entriesGather entries from another collection into a Map

Use the collectKeysAndValues method to add all the entries derived from another collection into the current Map.

collectKeysAndValues(collection, keyFunction, valueFunction) : MutableMap

(Mutable maps only) The key and value for each entry is determined by applying the keyFunction andvalueFunction (in each case, a Function) to each item in collection. Each is converted into a key-value entry andinserted into the Map. If a new entry has the same key as an existing entry in the calling map, the new entry's valuereplaces that of the existing entry.

Page 32: GS Collections Reference Guide

GS Collections | Iteration patterns

32

Finding, testing and putting valuesDetect a value by its key and, optionally, insert or return other values.

The updateValue…, getIfAbsent… and ifPresentApply methods locate a specified key and return a map value thatcorresponds to that key. Depending on whether a value is found at the given key, each method performs a specificaction.

add(Pair<K, V>) : value

Adds the given key-value pair to the map. It's a convenience method for working with Pairs, similar to put(K, V).

updateValue(key, Function0, Function) : value

If there is a value in the Map that corresponds to the specified key, applies the specified Function to the value andreplaces the value, otherwise applies the Function to the value supplied by the Function0 and puts the result as avalue in the map at the specified key.

updateValueWith(key, Function0, Function2, parameter) : value

If there is a value in the Map that corresponds to the specified key, applies the specified Function2 to the value andthe specified parameter and replaces the value with the result, otherwise applies the Function2 to the value suppliedby the Function0 and the parameter and puts the result as a value in the map at the specified key.

getIfAbsent(key, Function0) : element (or Function0 result)

Returns the value in the Map that corresponds to the specified key; if there is no value at the key, returns the resultof evaluating the specified Function0 (here, specifically, a code block without parameters that returns some object).

getIfAbsentPut(key, value) : element

Returns the value in the Map that corresponds to the specified key; if there is no value at the key, returns specifiedvalue, and puts that value in the map at the specified key.

getIfAbsentPut(key, Function0) : element (or Function0 result)

Returns the value in the Map that corresponds to the specified key; if there is no value at the key, returns the resultof evaluating the specified Function0, and puts that value in the map at the specified key

getIfAbsentPutWith(key, Function,parameter) : element (or Function result)

Returns the value in the Map that corresponds to the specified key; if there is no value at the key, returns the resultof evaluating the specified one-argument Function using the specified parameter, and put that value in the map atthe specified key.

getIfAbsentWith(key, Function, parameter) : element (or Function result)

Returns the value in the Map that corresponds to the specified key; if there is no value at the key, returns the resultof evaluating the specified Function and parameter.

ifPresentApply(key, Function) : (Function result)

If there is a value in the Map that corresponds to the specified key, returns the result of evaluating the specifiedFunction with the value, otherwise returns null.

Page 33: GS Collections Reference Guide

GS Collections | Iteration patterns

33

Flipping mapsReturn a new associative array where the position of the keys and values

have been flipped

flip() : Multimap

Since the values in the MapIterable are not necessarily unique, flip() returns a Multimap instead of a MapIterable.

flipUniqueValues() : MapIterable

Similar to MapIterable.flip() but asserts that the values in the MapIterable are unique and thus returns MapIterableinstead of Multimap. Throws IllegalArgumentException if the MapIterable contains duplicate values.

Page 34: GS Collections Reference Guide

GS Collections | Iteration patterns

34

Page 35: GS Collections Reference Guide

35

Chapter

2Collections and containers

Topics:

• Basic collection types• Primitive collections• Creating and converting

collections• Protecting collections

What is perhaps most distinctive about the GS Collections collection classesis what (quite properly) is hidden: their implementation of iteration patterns.Through this encapsulation, GS Collections is able to provide optimizedversions of each method on each container. For example, the first of theclasses we'll discuss here, FastList, is array-based; it iterates using indexedaccess directly against its internal array.

We'll begin with the GS Collections implementations of types having analogsin the Java Collections Framework (JCF). We'll then discuss the new typesBag and Multimap, the Immutable collections, and protective wrappers.

Page 36: GS Collections Reference Guide

GS Collections | Collections and containers

36

Basic collection typesThe most commonly-used GS Collections classes are FastList, UnifiedSet, and UnifiedMap. These collections serveas drop-in replacements for their corresponding types in the Java Collections Framework (JCF). Note that these GSCollections classes do not extend the JCF implementations; they are instead new implementations of both JCF and GSCollections interfaces, as this (highly-simplified) diagram summarizes:

The methods of the JCF types are primarily focused on adding or removing elements and similar, non-iterativeoperations. GS Collections interfaces provide methods for iteration patterns that for the most part, do not modify(mutate) the source collection, but rather return a new collection or information about the source collection.

ListIterableAn ordered collection that allows duplicate elements.

A ListIterable is a RichIterable which maintains its elements in insertion order and allows duplicate elements.

ListIterable has two mutable subinterfaces (MutableList and FixedSizeList) and one immutable subinterface(ImmutableList).

The ListIterable interface includes the binarySearch method, which is similar to the static method binarySearch onjava.util.Collections, but available from the object-oriented API.

MutableListA mutable ListIterable that implements java.util.List; the most common

implementation is FastList.

MutableList extends the JCF List interface and has the same contract. It also extends RichIterable , which providesthe iteration methods common to all collections.

The most common implementation of MutableList is FastList, which can be used to replace the familiarjava.util.ArrayList. Here is a comparison of how the two types can be created.

Class Example

ArrayList (JCF) List<String> comparison = new ArrayList<String>();comparison.add("Comcast");comparison.add("IBM");comparison.add("Microsoft");comparison.add("Microsoft");return comparison;

FastList (GSC) return FastList.newListWith("Comcast", "IBM", "Microsoft", "Microsoft");

Page 37: GS Collections Reference Guide

GS Collections | Collections and containers

37

The MutableList interface includes the sortThis and reverse methods, which are similar to the static methods sortand reverse on java.util.Collections. Both are mutating methods. Here is an example of sort using the JDK API andthen GS Collections.

Class Example

ArrayList (JCF) Collections.sort(people, new Comparator<Person>(){ public int compare(Person o1, Person o2) { int lastName = o1.getLastName().compareTo(o2.getLastName()); if (lastName != 0) { return lastName; } return o1.getFirstName().compareTo(o2.getFirstName()); }});

FastList(GSC Java 5+)

people.sortThis(new Comparator<Person>() { public int compare(Person o1, Person o2) { int lastName = o1.getLastName().compareTo(o2.getLastName()); if (lastName != 0) { return lastName; } return o1.getFirstName().compareTo(o2.getFirstName()); } });

FastList(GSC Java 8)

people.sortThis((o1, o2) -> { int lastName = o1.getLastName().compareTo(o2.getLastName()); if (lastName != 0) { return lastName; } return o1.getFirstName().compareTo(o2.getFirstName()); });

MutableList adds a new method called sortThisBy, which takes an attribute from each element using a Function andthen sorts the list by the natural order of that attribute.

Class Example

ArrayList (JCF) Collections.sort(people, Functions.toComparator(Person.TO_AGE));

FastList(GSC Java 5+)

people.sortThisBy(Person.TO_AGE);

FastList(GSC Java 8)

// Using a method referencepeople.sortThisBy(Person::getAge);// Using a lambda expressionpeople.sortThisBy(person -> person.getAge());

Here is an example comparing reverse using the JCF and using GS Collections; both are mutating methods.

Class Example

ArrayList (JCF) Collections.reverse(people);

FastList (GSC) people.reverseThis();

Page 38: GS Collections Reference Guide

GS Collections | Collections and containers

38

The toReversed method on MutableList lets you reverse a list without mutating it; that is, it returns a newMutableList. Here is an example of how to accomplish that in the JCF and in GS Collections.

Class Example

ArrayList (JCF) List<Person> reversed = new ArrayList<Person>(people)Collections.reverse(reversed);

FastList(GSC Java 5+)

MutableList<Person> reversed = people.toReversed();

The asReversed method returns a reverse-order view of the MutableList—a lazy iterable, like that returned byasLazy—that defers each element's evaluation until it is called for by a subsequent method.

Class Example

FastList(GSC Java 8)

ListIterable<Integer> integers = FastList.newListWith(1, 2, 3);// deferred evaluationLazyIterable<Integer> reversed = integers.asReversed();// deferred evaluationLazyIterable<String> strings = reversed.collect(String::valueOf);// forces evaluationMutableList<String> stringsList = strings.toList(); Assert.assertEquals(FastList.newListWith("3", "2", "1"), stringsList);

ArrayList to FastList

Here are some additional JCF to GS Collections refactoring examples.

Here is a Java Collections' ArrayList:

JCF List<Integer> integers = newArrayList<Integer>();integers.add(1);integers.add(2);integers.add(3);

And, here is the identical construction in GS Collections:

GSC (Java 5+) List<Integer> integers = new FastList<Integer>();integers.add(1);integers.add(2);integers.add(3);

In GS Collections, the static factory method newList can infer generic types

GSC (Java 5+) List<Integer> integers = FastList.newList();integers.add(1);integers.add(2);integers.add(3);

The GS Collections newListWith() method also provides varargs support, allowing any number of arguments

GSC (Java 5+) List<Integer> integers = FastList.newListWith(1, 2, 3);

You can also use the richer interface:

GSC (Java 5+) MutableList<Integer> integers = FastList.newListWith(1, 2, 3);

The list is never mutated; it can be made unmodifiable:

FastList.newListWith(1, 2, 3).asUnmodifiable();

Page 39: GS Collections Reference Guide

GS Collections | Collections and containers

39

There is also a form of newList that takes another iterable

GSC (Java 5+) FastList.newList(list);

These refactorings are analogous for UnifiedSet and UnifiedMap.

SetIterableA collection that allows no duplicate elements.

A SetIterable is a RichIterable that allows no duplicate elements. It can be sorted or unsorted.

• A SortedSetIterable is a SetIterable that maintains its elements in sorted order.• An UnsortedSetIterable is a SetIterable that maintains its elements in a hash table in an unpredictable order.

UnsortedSetIterable has two mutable subinterfaces (MutableSet and FixedSizeSet) and one immutable subinterface(ImmutableSet).

MutableSetA mutable SetIterable that implements java.util.Set; the most common

implementation is UnifiedSet.

MutableSet extends the JCF Set interface and has the same contract. It also extends RichIterable, which providesthe iteration methods common to all collections. An attempt to add duplicate elements to a MutableSet containeris ignored without throwing an exception. The order in which the elements are processed during iteration is notspecified.

The most common implementation is UnifiedSet, which can be used to replace the familiar java.util.HashSet.

Class Example

HashSet (JDK) Set<String> comparison = new HashSet<String>();comparison.add("IBM");comparison.add("Microsoft");comparison.add("Oracle");comparison.add("Comcast");return comparison;

UnifiedSet (GSC) return UnifiedSet.newSetWith("IBM", "Microsoft", "Verizon", "Comcast");

MutableSortedSetContains unique items that are sorted by some comparator or their

natural ordering.

A MutableSortedSet follows the same contract as a MutableSet, but sorts its elements by their natural order, orthrough a comparator parameter set by the user. The implementation for MutableSortedSet is TreeSortedSet.

Here is an example of a MutableSortedSet containing numbers in reverse order:

GSC (Java 5+) MutableSortedSet<Integer> sortedSetA = TreeSortedSet.newSet(Collections.<Integer>reverseOrder());MutableSortedSet<Integer> sortedSetB = TreeSortedSet.newSet(sortedSetA.with(1).with(2, 3).with(4, 5, 6));

MapIterableA collection of key/value pairs.

The MapIterable interface (extending RichIterable) is the top-level interface for collections of key/value pairs.

Page 40: GS Collections Reference Guide

GS Collections | Collections and containers

40

MapIterable has two mutable subinterfaces ( MutableMap and FixedSizeMap), one immutable subinterface(ImmutableMap). It is also is extended in mutable and immutable versions of maps with sorted elements(SortedMapIterable) and maps that allow lookup keys by (unique) values as well as the reverse (BiMap).

MutableMapA mutable MapIterable that implements java.util.Map; the most common

implementation is UnifiedMap.

The MutableMap interface defines an association of key/value pairs. It extends the MapIterable interface, whichfurnishes a set of iteration methods especially for the key/value structure of a Map collection. These includeunmodifiable views of keys, values or pair-entries using the keysView, valuesView and entriesView methods,respectively.

The mutable subinterfaces of MapIterable also extend the JCF Map interface.

The most common implementation of MutableMap is UnifiedMap, which can replace the Java class HashMap.

Class Example

HashMap (JDK) Map<Integer, String> map = new HashMap<Integer, String>();map.put(1, "1");map.put(2, "2");map.put(3, "3");

UnifiedMap(GSC)

MutableMap<Integer, String> map = UnifiedMap.newWithKeysValues(1, "1", 2, "2", 3, "3");

MutableSortedMapA sorted Map.

A MutableSortedMap follows the same contract as a MutableMap, but sorts its elements by their natural order, orthrough a comparator parameter set by the user. The implementation for MutableSortedMap is TreeSortedMap.

This code block creates a TreeSortedMap which sorts in reverse order:

GSC (Java 5+) MutableSortedMap<String, Integer> sortedMap = TreeSortedMap.newMapWith(Comparators.<String>reverseNaturalOrder(), "1", 1, "2", 3, "3", 2, "4", 1);

BiMapA map that allows users to add key-value pairs and look up from either

direction

BiMap is an interface that defines a bi-directional map, i.e, a map that allows users to look up from both directions.Both the keys and the values in a BiMap are unique.

BiMap extends MapIterable and MutableBiMap extends MutableMap. The standard implementation isHashBiMap.

GSC (Java 5+) MutableBiMap<Integer, String> biMap = HashBiMap.newWithKeysValues(1, "1", 2, "2", 3, "3");

The distinctive methods on MutableBiMap are put, forcePut and inverse.

Page 41: GS Collections Reference Guide

GS Collections | Collections and containers

41

put() MutableBiMap.put behaves like put on a regular map, except that it throws an exceptionwhen you try to add a duplicate value.

MutableBiMap<Integer, String> biMap = HashBiMap.newMap(); biMap.put(1, "1"); // behaves like a regular put() biMap.put(1, "1"); // no effect biMap.put(2, "1"); // throws IllegalArgumentException since value "1" is already present

forcePut() MutableBiMap.forcePut behaves like MutableBiMap.put, except that it silently removesthe map entry with the same value before putting the key-value pair in the map. MutableBiMap<Integer, String> biMap = HashBiMap.newMap(); biMap.forcePut(1, "1"); // behaves like a regular put() biMap.forcePut(1, "1"); // no effect biMap.forcePut(1, "2"); // replaces the [1,"1"] pair with [1, "2"] biMap.put(2, "2"); // removes the [1, "2"] pair before putting Assert.assertFalse(biMap.containsKey(1)); Assert.assertEquals(HashBiMap.newWithKeysValues(2, "1"), biMap);

inverse() MutableBiMap.inverse returns a reversed view of the BiMap. MutableBiMap<Integer, String> biMap = HashBiMap.newWithKeysValues(1, "1", 2, "2", 3, "3"); MutableBiMap<String, Integer> inverse = biMap.inverse(); Assert.assertEquals("1", biMap.get(1)); Assert.assertEquals(1, inverse.get("1")); Assert.assertTrue(inverse.containsKey("3")); Assert.assertEquals(2, inverse.put("2", 4));

BagAn unordered collection that allows duplicates.

A Bag is a RichIterable that allows duplicate elements and efficient querying of the number of occurrences of eachelement. It can be sorted or unsorted.

• A SortedBag is a Bag that maintains its elements in sorted order.• An UnsortedBag is a Bag that maintains its elements in a hash table in an unpredictable order.

UnsortedBag has two subinterfaces, MutableBag and ImmutableBag. SortedBag has two subinterfaces,MutableSortedBag and ImmutableSortedBag.

A Bag is conceptually like a Map from elements to the number of occurrences of that element.

AppleFor example, this list:

Pear

Orange

Orange

Apple

Orange

could create this bag: Pear 1

Orange 3

Apple 2

GSC (Java 5+) return MutableBag < String > bag = HashBag.newBagWith("Apple", "Pear", "Orange", "Apple", "Apple", "Orange");

The distinctive methods on Bag are:

Page 42: GS Collections Reference Guide

GS Collections | Collections and containers

42

occurrencesOf Returns the occurrences of a distinct item in the bag.

forEachWithOccurrences For each distinct item, with the number of occurrences, executes the specifiedprocedure.

toMapOfItemToCount Returns a map with the item type to its count as an Integer.

MutableBagA mutable unordered collection allowing duplicates; the most common

implementation is HashBag.The MutableBag interface includes methods for manipulating the number of occurrences of an item. For example,to determine the number of unique elements in a MutableBag, use the sizeDistinct method. The most commonimplementation of MutableBag is HashBag.

GSC (Java 5+) return MutableBag < String > bag = HashBag.newBagWith("Apple", "Pear", "Orange", "Apple", "Apple", "Orange");

The distinctive methods on MutableBag are:

addOccurrences(T item, int occurrences) Increments the count of the item in the bagby a count specified by occurrences.

removeOccurrences(Object item, int occurrences) Decrements the count of the item in the bagby a count specified by occurrences.

setOccurrences(T item, int occurrences) Mutates the bag to contain the specifiednumber of occurrences of the item.

MutableSortedBagA sorted collection that allows duplicates.

A MutableSortedBag is a Bagthat maintains order. It defaults to natural order, but can take a comparator to sort. Themost common implementation of MutableSortedBag is TreeBag which uses a SortedMap as its underlying data store.

For example, this MutableSortedBag would contain integers sorted in reverse order:

GSC (Java 5+) MutableSortedBag<Integer> revIntegers = TreeBag.newBagWith(Collections.reverseOrder(), 4, 3, 3, 2, 2, 2, 1, 1);

StackIterableA collection that maintains "last-in, first-out" order, iterating over

elements in reverse insertion order.

A StackIterable is a RichIterable enforcing a "last-in, first-out" order; its methods always iterate over elements inreverse insertion order, (beginning with the most-recently added element). For example the getFirst method returnsthe the last element to have been added — the "top" of the stack.

StackIterable has a mutable and an immutable subinterface (MutableStack and ImmutableStack, respectively).

Page 43: GS Collections Reference Guide

GS Collections | Collections and containers

43

MutableStackA mutable collection that maintains "last-in, first-out" order, iterating

over elements in reverse insertion order.

The most common implementation of MutableStack is ArrayStack. The closest JCF equivalent to ArrayStack isjava.util.Stack, which extends Vector but does not enforce strict LIFO iteration.

The distinctive methods on MutableStack are push, pop, and peek.

push Adds a new element to the top of the stack

pop Returns the top (most recently-added) element and removes it from the collection.

pop(int count) Returns a ListIterable of the number of elements specified by the count, beginningwith the top of the stack.

peek Returns but does not remove the top element. Note that, on a stack, getFirstlikewise returns the top element, and that getLast throws an exception.

peek(int count ) Returns a ListIterable of the number of elements specified by the count, beginningwith the top of the stack; does not remove the elements from the stack.

peekAt(int index ) Returns the element at index.

ArrayStack can replace java.util.Stack.

Class Example

Stack (JCF) Stack stack = new Stack(); stack.push(1); stack.push(2); stack.push(3);

ArrayStack(GSC)

MutableStack mutableStack = ArrayStack.newStackWith(1, 2, 3);

MultimapA map-like container that can have multiple values for each key

In a Multimap container, each key can be associated with multiple values. It is, in this sense, similar to a Map, butone whose values consist of individual collections of a specified type, called the backing collection. A Multimap isuseful in situations where you would otherwise use Map<K, Collection<V>>.

Unlike the other basic GS Collections containers, Multimap does not extend RichIterable, but resides along with itssubinterfaces in a separate API. The RichIterable methods are extended by the backing collection types.

Depending on the implementation, the "values" in a Multimap can be stored in Lists, Sets or Bags. For example, theFastListMultimap class is backed by a UnifiedMap that associates each key with a FastList that preserves the orderin which the values are added and allows duplicate to be added.

A Multimap is the type returned by the groupBy method. Here is an example in which we group a list of words bytheir length, obtaining a Multimap with integer (word=length) keys and lists of words having that length for values.

This simple list: here produces a List-backed Multimap: key value<list>

are 1 a

a 3 are,few,are,not,too

few 4 here,that,long

Page 44: GS Collections Reference Guide

GS Collections | Collections and containers

44

words 5 words

that

are

not

too

long

The code that performs this action uses the groupBy method.

GSC (Java 5+) MutableList<String> words = FastList.newListWith("here", "are", "a", "few", "words", "that", "are", "not", "too", "long");MutableListMultimap<Integer, String> multimap = words.groupBy(StringFunctions.length());

GSC (Java 8) MutableList<String> words = FastList.newListWith("here", "are", "a", "few", "words", "that", "are", "not", "too", "long");MutableListMultimap<Integer, String> multimap = words.groupBy(String::length);

The interface MutableListMultimap extends the Multimap interface and tells us the type of its backing collections.Since words is a MutableList, the output is a MutableListMultimap. The word "are" is allowed to occur twice in thelist at key 3.

If we change words to a MutableSet, the result will be a MutableSetMultimap, which will eliminate duplicate entries.

GSC (Java 5+) MutableSet<String> words = UnifiedSet.newSetWith("here", "are", "a", "few", "words", "that", "are", "not", "too", "long");MutableSetMultimap<Integer, String> multimap = words.groupBy(StringFunctions.length());

GSC (Java 8) MutableSet<String> words = UnifiedSet.newSetWith("here", "are", "a", "few", "words", "that", "are", "not", "too", "long");MutableSetMultimap<Integer, String> multimap = words.groupBy(String::length);

With duplicates removed, only four 3-letter words remain. key value <list>

1 a

3 too,are,few,not,

4 long,here,that

5 words

Primitive collectionsContainers for iterating over collections of Java primitives.

GS Collections has memory-optimized lists, sets, stacks, maps, and bags for all the primitive types: int, long, float,char, byte, boolean, short, and double.

The interface hierarchies for primitive types correspond closely with the interface hierarchy for regular Objectcollections. For example, the collection interfaces for int include the following:

interface analogous to

IntIterable RichIterable

MutableIntCollection MutableCollection

IntList ListIterable

Page 45: GS Collections Reference Guide

GS Collections | Collections and containers

45

MutableIntList MutableList

Primitive Lists The primitive list implementations are backed by an array like FastList, but with a primitivearray instead of an Object[]. They are named IntArrayList, FloatArrayList etc.

BooleanArrayList is a special case. Current JVMs use one byte per boolean in aboolean[] (instead of one bit per boolean). Thus the BooleanArrayList is backed by ajava.util.BitSet as an optimization.

To create an IntArrayList, use one of the following:

IntArrayList emptyList = new IntArrayList();IntArrayList intList = IntArrayList.newListWith(1, 2, 3);IntArrayList listFromIntIterable = IntArrayList.newListWith(IntHashSet.newSetWith(1, 2, 3));

IntInterval An IntInterval is a range of ints that may be iterated over using a step value. (Similar toInterval, but uses primitive ints instead of the wrapper Integers.)

Assert.assertEquals(IntArrayList.newListWith(1, 2, 3), IntInterval.oneTo(3));Assert.assertEquals(IntArrayList.newListWith(1, 3, 5), IntInterval.oneToBy(5, 2));

Primitive Sets The primitive set implementations are hash-table backed. They are named IntHashSet,FloatHashSet etc. BooleanHashSet is implemented using a single integer to hold one offour possible states: ([], [F], [T], or [T, F]). All other sets use open addressing and quadraticprobing.

Primitive Stacks Similar to ArrayStack but optimized for primitives.

Primitive Bags Similar to HashBag, but both item and count are primitives.

Primitive Maps There are three types of primitive maps:

• Object To Primitive (ObjectIntHashMap, ObjectFloatHashMap etc.)• Primitive To Object (IntObjectHashMap, FloatObjectHashMap etc.)• Primitive To Primitive (IntIntHashMap, IntLongHashMap etc.)

All the maps use open addressing and quadratic probing.

There are some common arithmetic operations that can be performed on all primitive collections (except booleancollections).

IntArrayList intList = IntArrayList.newListWith(1, 2, 3);Assert.assertEquals(6, intList.sum());Assert.assertEquals(2, intList.average());Assert.assertEquals(2, intList.median());

Page 46: GS Collections Reference Guide

GS Collections | Collections and containers

46

Primitive maps with numeric value types (not boolean or Object) have a method addToValue that adds the givenamount to the value at the given key and returns the updated value.

MutableByteIntMap map = new ByteIntHashMap();Assert.assertEquals(1, map.addToValue((byte) 0, 1));Assert.assertEquals(ByteIntHashMap.newWithKeysValues((byte) 0, 1), map);

Assert.assertEquals(11, map.addToValue((byte) 0, 10));Assert.assertEquals(ByteIntHashMap.newWithKeysValues((byte) 0, 11), map);

All primitive collections have immutable counterparts, and unmodifiable and synchronized wrappers. See theProtecting collections topic for more information.

Creating and converting collectionsThe following methods can be used to convert one container type to another. All of these methods are onRichIterable. To create immutable and fixed-size collections, refer to Immutable collections.

toList() : MutableList Converts the collection to the default MutableListimplementation (FastList).

toSet() : MutableSet Converts the collection to the default MutableSetimplementation (UnifiedSet).

toBag() : MutableBag Converts the collection to the default MutableBagimplementation (HashBag).

toMap(keyFunction, valueFunction) : MutableMap Converts the collection to the default MutableMapimplementation (UnifiedMap) using the specifiedkeyFunctions and valueFunctions.

toSortedList() : MutableList Converts the collection to the default MutableListimplementation (FastList) and sorts it using the naturalorder of the elements.

toSortedList(Comparator) : MutableList Converts the collection to the default MutableListimplementation (FastList) and sorts it using thespecified Comparator.

These methods always return new mutable copies: for example, calling toList on a FastList, returns a new FastList.

To create a new collection of the same type

newEmpty()> : MutableCollection Creates a new, empty, and mutable container of thesame collection type. For example, if this instance is aFastList, this method will return a new empty FastList.If the class of this instance is immutable (see below) orfixed size (for example, a singleton List) then a mutablealternative to the class is returned.

Protecting collectionsGS Collections provides special interfaces for controlling and preventing changes to containers and their elements.

• Immutable collection: a copy that is permanently unchangeable.• Unmodifiable collection: a read-only interface wrapped over a backing collection that remains mutable.

Page 47: GS Collections Reference Guide

GS Collections | Collections and containers

47

• Synchronized collection: a wrapper that presents a mostly thread-safe view of a collection.

Immutable collectionsA read-only snapshot of a collection; once created, it can never be

modified.

All of the basic containers in GS Collections have interfaces for both mutable and immutable (unchangeable) forms.This departs somewhat from the JCF model, in which most containers are mutable.

An immutable collection is just that—once created, it can never be modified, retaining the same internal referencesand data throughout its lifespan. An immutable collection is equal to a corresponding mutable collection with thesame contents; a MutableList and an ImmutableList can be equal.

Because its state does not change over time, an immutable collection is always thread-safe. Using immutablecollections where feasible can serve to make your code easier to read and understand.

All of the interfaces and implementations discussed so far in this topic have been mutable versions of their respectivetypes. Each of these containers has an immutable counterpart. These are the corresponding interfaces:

Mutable types Immutable types

MutableList ImmutableList

MutableSet ImmutableSet

MutableBag ImmutableBag

MutableMap ImmutableMap

MutableMultimap ImmutableMultimap

MutableStack ImmutableStack

The method that returns an immutable collection for all container types is toImmutable():

MutableCollection. toImmutable() : ImmutableCollection

Returns an immutable copy of a type corresponding to the source MutableCollection.

StackIterable. toImmutable() : ImmutableStack

Returns an immutable copy of a MutableStack, returns the same iterable for an ImmutableStack.

ListIterable. toImmutable() : ImmutableList

Returns an immutable copy of a MutableList, returns the same iterable for an ImmutableList.

SortedMapIterable. toImmutable() : ImmutableSortedMap

Returns an immutable copy of a MutableSortedMap, returns the same iterable for an ImmutableSortedMap.

UnsortedMapIterable. toImmutable() : ImmutableMap

Returns an immutable copy of a MutableMap, returns the same iterable for an ImmutableMap.

An immutable-collection interface lacks mutating methods, such as add and remove. Instead, immutable collectionshave methods that return new, immutable copies with or without specified elements:

Page 48: GS Collections Reference Guide

GS Collections | Collections and containers

48

ImmutableCollection. newWith(element) : ImmutableCollection

Returns a new immutable copy of ImmutableCollection with element added.

ImmutableCollection. newWithAll(Iterable) : ImmutableCollection

Returns a new immutable copy of ImmutableCollection with the elements of Iterable added.

ImmutableCollection. newWithout(element) : ImmutableCollection

Returns a new immutable copy of ImmutableCollection with element removed.

ImmutableCollection. newWithoutAll(Iterable) : ImmutableCollection

Returns a new immutable copy of ImmutableCollection with the elements of Iterable removed.

Note that the iteration methods of an immutable container - such as select, reject, and collect - also produce newimmutable collections.

Immutable Collection Factory Classes

The factory classes Lists, Sets, Bags, and Maps create immutable collections. These factories also provide methodsfor creating fixed-size collections, which have been superseded by immutable collections.

GSC (Java 5+) ImmutableList<Integer> immutableList = Lists.immutable.of(1, 2, 3);ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3);Bag<Integer> immutableBag = Bags.immutable.of(1, 2, 2, 3);ImmutableMap<Integer, String> immutableMap = Maps.immutable.of(1, "one", 2, "two", 3, "three");

These factories highlight yet another benefit of immutable collections: they let you create efficient containers that aresized according to their contents. In cases where there are many, even millions of collections, each with a size lessthan 10, this is an important advantage.

Protective wrappersWrapper classes providing read-only or thread-safe views of a

collection.

Unmodifiable Collections

In both the JCF and GS Collections, a collection may be rendered unmodifiable. In GS Collections, this is done bymeans of the asUnmodifiable method, which returns a read-only view of the calling collection. This means that themutating methods of the collection (e.g., add, remove) are still present, but throw exceptions if called.

MutableCollection. asUnmodifiable() : MutableCollection (read-only)

Returns a read-only view of the source collection.

MutableIntCollection.asUnmodifiable() : MutableIntCollection.(read-only)

Returns a read-only view of the source primitive collection. There are similar methods for each primitive type(MutableFloatCollection.asUnmodifiable() etc.)

Synchronized CollectionsGS Collections provides a wrapper for rendering a modifiable but thread-safe view that holds a lock when a method iscalled and releases the lock upon completion.

Page 49: GS Collections Reference Guide

GS Collections | Collections and containers

49

MutableCollection. asSynchronized() : MutableCollection

Returns a synchronized copy of the source collection.

MutableIntCollection. asSynchronized() : MutableIntCollection.

Returns a synchronized copy of the source primitive collection. There are similar methods for each primitivetype (MutableFloatCollection.asSynchronized() etc.)

Page 50: GS Collections Reference Guide

GS Collections | Collections and containers

50

Page 51: GS Collections Reference Guide

51

Chapter

3Code blocks

Topics:

• Predicate• Function• Procedure

A code block, in GS Collections terms, is a single-abstract-method objectthat is passed as a parameter to an iteration method. It is an abstraction thatrepresents the evaluation of each element in the course of iteration. It helpsus to further separate what is being done from how it is done. This topicenumerates the basic code block types - the GS Collections interfaces andclasses - and the relevant methods to which they apply.

What we call a "code block" in GS Collections is roughly analogous to alambda expression. The closest analog to a lambda in Java in versions prior toJava 8 is the anonymous inner class.

Here are two examples, one implementing Predicate using an anonymousinner class, and the other using a Java 8 lambda expression.

GSC (Java 5+)

MutableList<Person> texans = this.people.select(new Predicate<Person>() { public boolean accept(Person each) { return each.getAddress().getState().equals("TX"); }});Verify.assertSize(1, texans);

GSC (Java 8)

MutableList<Person> texans = this.people.select( each -> each.getAddress().getState().equals("TX"));Verify.assertSize(1, texans);

In each case, if the value of state field for any element in people equals "TX"then the select method includes that element in the result list, texans.

This chapter introduces the most commonly-used code blocks and the GSCollections methods that use them. Along with the code block types describedhere, the current version of GS Collections offers a full suite of primitivecode blocks (and corresponding code block factories like IntFunction,IntPredicate, IntProcedure etc.) These code blocks are used by methods onprimitive collections.

About parameter and argument:

These terms are often (if inaccurately) used interchangeably to refer tomethod or function inputs. (The usual distinction holds that parameter refersto a formal definition of the input, while argument denotes the actual values.)For the limited purposes of this guide - and in particular the scope of thistopic - we use parameter to specify the input to an iteration method - in thisexample, select. These parameters can take the form of the code block (asdescribed in this topic), which itself is an object with methods. The input for a

Page 52: GS Collections Reference Guide

GS Collections | Code blocks

52

code block we refer to here as the argument - in this example, the argument iseach (the "current element" upon each iteration).

Page 53: GS Collections Reference Guide

GS Collections | Code blocks

53

PredicateA Predicate is a single-argument code block that evaluates an element and returns a boolean value. Also known as adiscriminator or filter, it is used with the filtering methods select, reject, detect, anySatisfy, allSatisfy, and count.

Description Arguments Returns Used By

Predicate Evaluates each element of acollection (the argument), and returnsa boolean value.

One (T) boolean select, reject,detect,anySatisfy,allSatisfy, count

Predicate2 Evaluates each element of acollection (the first argument); thesecond argument is a parameterpassed into the Predicate2 from thecalling method.

Two (T,P) boolean selectWith,rejectWith,detectWith,anySatisfyWith,allSatisfyWith,countWith

The accept method is implemented to indicate the object passed to the method meets the criteria of this Predicate.Here is a Predicate implemented in a select method as an anonymous inner class:

GSC (Java 5+) MutableList<Integer> greaterThanFifty = list.select(new Predicate<Integer>() { public boolean accept(Integer each) { return each > 50; } });

The Predicates class can be used to build common filters. Predicates supports equals, not equals, less than, greaterthan, less than or equal to, greater than or equal to, in, not in, and, or, and numerous other predicate-type operations.

Examples with select:

GSC (Java 5+) MutableList<Integer> myList =...MutableList<Integer> selected1 = myList.select(Predicates.greaterThan(50));

Predicate Factories

Predicates Supports equal, greaterThan, lessThan, in, notIn, and, or,instanceOf, null, notNull, anySatisfy, allSatisfy, etc.

Predicates2 For Predicate2s that work with methods suffixed with"With," such as selectWith.

StringPredicates Supports empty, notEmpty, contains, isAlpha,isNumeric, isBlank, startsWith, endsWith, matches, etc.

IntegerPredicates Supports isEven, isOdd, isPositive, isNegative, isZero.

LongPredicates Supports isEven, isOdd, isPositive, isNegative, isZero.

FunctionThe Function code block in its most common usage takes each element of a collection as the argument to the code-block logic. It selects an attribute from the element via a "getter" – its valueOf method. It then returns a computedvalue or, if no evaluation logic is performed, the attribute itself.

Page 54: GS Collections Reference Guide

GS Collections | Code blocks

54

Function code blocks are used as a parameter in a variety of common GS Collections methods:

• With the collect method to calculate a new value for each element of a given collection, and then return atransformed collection of the same type.

• With the groupBy method to generate keys for each nested collection (values) of a new Multimap.• With the flatCollect method, where it must return an Iterable that gets "flattened" with other iterables, into a

single collection.• With the Predicates factory's attributeOperator methods - such as attributeLessThanOrEqualTo - to build

Predicate (boolean) objects.

Description Arguments Returns Used By

Function(transformer)

Evaluates each element of acollection as the argument to the codeblock logic and returns a computedvalue

One (T) Object (V) collect,flatCollect,groupBy

Function0 Executes and returns a value (likeCallable); represents deferredevaluation.

Zero Object (V) getIfAbsent,getIfAbsentPut,ifPresentApply

Function2 Used by injectInto methods; takesthe accumulator argument as the firstargument, and the current item of thecollection as the second argument.

Two (T,P) Object (V) forEachEntryinjectIntocollectWith

Function3 Used by injectIntoWith; takesthe injected argument as the firstargument, the current item of thecollection as the second argument,and the specified parameter for thethird argument. The result of eachsubsequent iteration is passed in asthe first argument.

Three (T,P,?) Object (V) injectIntoWith

Function Factories

FunctionsgetToClass getToString

getPassThru

Functions0newFastList newHashBag

newUnifiedMap newUnifiedSet

nullValue value

Functions2 fromFunction

StringFunctionsfirstLetter length

subString toFirstChar

toInteger toLowerCase

toPrimitive [type] toUpperCase

trim firstLetter

Page 55: GS Collections Reference Guide

GS Collections | Code blocks

55

Other Functions

IfFunction Supports if and else using a discriminator with Function.

CaseFunction This allows for multi-conditional or rule based selector using Predicates (use this withguidance).

ProcedureA Procedure is a code block that performs an evaluation on its single argument and returns nothing. A Procedure ismost commonly used with ForEach -pattern methods.

Count and calculate

CountProcedure Apply a Predicate to an object and increment a count if it returns true.

CounterProcedure Wrap a specified block and keeps track of the number of times it is executed.

Control execution

ChainedProcedure Chain together blocks of code to be executed in sequence;ChainedProcedure can chain Procedures, Functions or Function2s.

CaseProcedure Create an object form of a case statement, which instead of being based on asingle switch value is based on a list of discriminator or block combinations.For the first discriminator that returns true for a given value in the casestatement, the corresponding block will be executed.

IfProcedure Evaluate the specified block only when a Predicate returns true. If the resultof evaluating the Predicate is false, and the developer has specified that thereis an elseProcedure, then the elseProcedure is evaluated.

IfProcedureWith Same as IfProcedure, but with a second argument passed from the callingiteration method.

ObjectIntProcedure Takes an int as a second argument; this is usually the index of the currentelement of a collection.

Modify collections and maps

CollectionAddProcedure Add elements to the specified collection when block methods arecalled.

CollectionRemoveProcedure Remove element from the specified collection when block methodsare called.

MapPutProcedure Use a specified Function to calculate the key for an object and putsthe object into the specified Map at the position of the calculatedkey.

MultimapPutProcedure Use a specified Function to calculate the key for an object and putsthe object with the key into the specified MutableMultimap.

Page 56: GS Collections Reference Guide

GS Collections | Code blocks

56

Procedure Factories

Proceduresappend bind

caseDefault fromObjectIntProcedure

ifElse ifTrue

println synchronizedEach

Procedures2addToCollection fromProcedure

Page 57: GS Collections Reference Guide

57

Appendix

AHelp

Topics:

• Verify• Q & A• GS Collections Cheat Sheet

Additional reference pages.

Page 58: GS Collections Reference Guide

GS Collections | Help

58

VerifyA testing utility.

GS Collections includes a jar file called gs-collections-testutils. This utility helps with writing unit tests. There aremany collection-specific assertions, such as

MutableList<Integer> list = FastList.newListWith(1, 2, 3);Verify.assertListsEqual(FastList.newListWith(1, 2, 3), list);

to test that two lists are equal. It is implemented as an extension of JUnit. The most important class is Verify. Hereare some examples:

Verify.assertSize(2, customersFromLondon);

//instead ofAssert.assertEquals(2, customersFromLondon.size());

Verify.assertEmpty(FastList.newList());Verify.assertNotEmpty(FastList.newListWith(1));Verify.assertContains(1, FastList.newListWith(1));

Q & A

Here are some of the most commonly asked questions and answers regarding GS Collections.

Why GS Collections?

• Improves readability and reduces duplication of iteration code (enforces DRY/OAOO).• Implements several high-level iteration patterns (select, reject, collect, inject into, etc.) on "humane" container

interfaces which are extensions of the JDK interface.• Provides a consistent mechanism for iterating over Collections, Arrays, Maps, and Strings.• Provides replacements for ArrayList, HashSet, and HashMap optimized for performance and memory usage.• Performs more "behind-the-scene" optimizations in utility classes.• Encapsulates a lot of the structural complexity of parallel iteration and lazy evaluation.• Adds new containers including Bag, Interval, Multimap, and immutable versions of all types.• Has been under active development since 2005 and is a mature library.

Why is Goldman Sachs open-sourcing GS Collections?

• We believe that GS Collections offers a significant advantage over existing solutions. We hope others will benefitfrom it.

• We believe in the power of the technical community to help improve GS Collections.• Technology is a huge part of what we do at Goldman Sachs. GS Collections exemplifies our commitment to

technology.• We use open source software in many of our operations. We have benefited from the work of others and we'd like

to give something back.

Does Goldman Sachs use GS Collections?

Yes, we use GS Collections in many of our internal applications.

What makes GS Collections different from other, similar frameworks?

The most obvious distinction for Java developers is the placement of collection-related iteration methods on thecontainer class itself. This means we can implement methods that are common to all container types, and optimizethem - in terms of memory and processor use - specifically for each type. The resulting code is easier (for humans) toread and understand.

Page 59: GS Collections Reference Guide

GS Collections | Help

59

When can I start using Java 8 lambdas and method references with GS Collections?

GS Collections is Java 8 ready today! All of our iteration patterns are able to fully function as seen in the codeexamples of the reference guide.

GS Collections Cheat SheetRichIterable API Description

allSatisfy Returns true if all elements satisfy a Predicate; short-circuits execution.

anySatisfy Returns true if any element satisfies a Predicate; short circuits execution.

appendString Prints a string representation of this collection onto the given Appendable; prints the stringreturned by makeString.

asSynchronized Returns a synchronized collection.

asUnmodifiable Returns an unmodifiable collection.

chunk Splits a collection into fixed-size chunks; the final chunk will be smaller if the collectiondoesn't divide evenly.

collect Transforms elements using a Function into a new collection; n.

count Returns the number of elements that satisfy a Predicate.

detect Finds the first element that satisfies a Predicate; short circuits execution

flatCollect Transforms and flattens elements using a Function.

forEach Executes a Procedure on each element, doesn't return anything

groupBy Gets a key for each element using a Function and puts the key and element into a Multimap.

groupByEach Special case of groupBy used were the Function returns a collection; analogous to thedifference between collect and flatCollect.

injectInto Returns the final result of all evaluations using as the arguments each element of thecollection, and the result of the previous iteration's evaluation.

makeString Converts the collection to a string using optional start, end, and separator strings.

max Returns the maximum element using either the natural order or a Comparator.

maxBy Gets some attribute from each element and returns the element whose attribute is maximal.

min Returns the minimum element using either the natural order or a Comparator.

minBy Gets some attribute from each element and returns the element whose attribute is minimal.

reject Returns the elements of a collection that do not satisfy a Predicate.

select Returns the elements of a collection that satisfy a Predicate.

sortThis Sorts the internal data structure of a MutableList using the natural order of the elements or aComparator.

sortThisBy Gets some attribute from each element using a Function and sorts the list by the naturalorder of that attribute.

toBag Converts the collection to the default MutableBag implementation.

toImmutable Returns an immutable collection.

Page 60: GS Collections Reference Guide

GS Collections | Help

60

RichIterable API Description

toList Converts the collection to a MutableList implementation.

toMap Converts collection to a MutableMap implementation using specified key and valuefunctions.

toSet Converts the collection to a MutableSet implementation.

toSortedList Converts the collection to a MutableList implementation and sorts it using the natural orderof the elements.

toSortedListBy Gets some attribute from each element using a Function and returns a new list sorted by thenatural order of that attribute.

toSortedSet Converts the collection to a MutableSortedSet implementation and sorts it using the naturalorder of the elements.

toSortedSetBy Converts the collection to a MutableSortedSet implementation and sorts it based on thenatural order of the attributes returned by the Function.

zip Takes a second RichIterable and pairs up all the elements; if one of the two RichIterables islonger, its remaining elements are ignored.

zipWithIndex Zips the collection with the Integer indexes 0 to n-1.

Interfaces Description

Bag Analogous to JCF Map <K, Integer>.

Multimap Analogous to JCF Map <K, Iterable<V>>.

MutableList Analogous to JCF List .

MutableMap Analogous to JCF Map .

MutableSet Analogous to JCF Set .

Pair Container that holds two related objects.

Blocks Description

Function Transforms one type (T) to another (V).

Function0 A zero-argument lambda (Java 8) that returns some type; a factory.

Function2 Used by injectInto methods; takes the accumulator argument as the first argument, and thecurrent item of the collection as the second argument.

ObjectIntProcedure Takes an int as a second argument; this is usually the index of the current element of acollection; doesn't return anything.

Predicate Takes an object of some type (T) and returns a boolean.

Predicate2 Primarily used in methods like selectWith, detectWith, rejectWith. The first argument isthe element of the collection being iterated over, and the second argument is a parameterpassed into the Predicate2 from the calling method.

Procedure Takes an object of some type (T) and doesn't return anything.

Procedure2 Takes two objects of types (T1, T2) and doesn't return anything.

Page 61: GS Collections Reference Guide

GS Collections | Help

61

Static utility Classes To interoperate with

ArrayIterate Arrays

Iterate All iterables

LazyIterate All iterables for lazy evaluation

ListIterate Lists

MapIterate Maps

ParallelArrayIterate Arrays for parallel iteration

ParallelIterate Iterables for parallel iteration

ParallelMapIterate Maps for parallel iteration

StringIterate strings

Page 62: GS Collections Reference Guide

GS Collections | Help

62