GS Collections and Java 8 Functional, Fluent, Friendly & Fun!
GS Collections and Java 8 Functional, Fluent, Friendly & Fun!
DIVISION
Agenda
TECHNOLOGY
DIVISION
Introductions
Lost and Found
Streams
The Iceberg
APIs
Fluency
Memory Efficiency
Method references are awesome
Framework Comparisons
2
What is GS Collections?
TECHNOLOGY
DIVISION
GS Collections Kata
Internal training developed in 2007
Taught to > 1,500 GS Java developers
Hosted on GitHub w/ Apache 2.0 License
github.com/goldmansachs/gs-collections-kata
3
Paradise Lost
1997 - Smalltalk Best
Practice Patterns (Kent
Beck)
do:
select:
reject:
collect:
detect:
detect:ifNone:
inject:into:
TECHNOLOGY
DIVISION
2007 - Implementation
Patterns (Kent Beck)
Map
List
Set
Paradise Found
detect
select
Pattern in GS Collections w/
Lambdas
list.detect(each -> each > 50);
list.collect(Object::toString);
int result = 3;
for (Integer each : list)
result = result + each;
list.injectInto(3, Integer::sum);
inject
into
collect
any
satisfy
all
satisfy
reject
Pattern in Smalltalk-80
TECHNOLOGY
DIVISION
Stream<Integer> result =
list.stream().filter(e -> e <= 50);
any
Match
list.asLazy().collect(Object::toString);
Integer result =
list.asLazy().injectInto(3,
Integer::sum);
Stream<Integer> result =
list.stream().filter(e -> e > 50);
boolean any =
list.stream().anyMatch(e -> e > 50);
all
Match
inject
into
LazyIterable<String> result =
boolean all =
list.stream().allMatch(e -> e > 50);
map
boolean all =
list.asLazy().allSatisfy(e -> e > 50);
collect
boolean any =
list.asLazy().anySatisfy(e -> e > 50);
Java 8 Streams
Stream<String> result =
list.stream().map(Object::toString);
reduce
detect
select
LazyIterable<Integer> result =
list.asLazy().reject(e -> e > 50);
any
satisfy
LazyIterable<Integer> result =
list.asLazy().select(e -> e > 50);
all
satisfy
reject
GS Collections LazyIterable
TECHNOLOGY
DIVISION
Integer result =
list.stream().reduce(3, Integer::sum);
6
List<Integer> result =
list.stream().filter(e -> e <=
50).collect(Collectors.toList());
boolean result =
list.stream().anyMatch(e -> e > 50);
boolean all =
list.allSatisfy(e -> e >
50);
boolean result =
list.stream().allMatch(e -> e > 50);
map
List<String> result =
MutableList<String> result =
list.collect(Object::toString);
Integer result =
list.injectInto(3,
Integer::sum);
reduce
inject
into
collect
boolean any =
list.anySatisfy(e -> e >
50);
any
Match
List<Integer> result =
list.stream().filter(e -> e >
50).collect(Collectors.toList());
all
Match
detect
select
Integer result =
list.stream().filter(e -> e > 50).findFirst().orElse(null);
any
satisfy
MutableList<Integer> result =
list.reject(e -> e > 50);
Java 8 Streams
all
satisfy
MutableList<Integer> result =
list.select(e -> e > 50);
reject
Eager GS Collections
Integer result =
list.detect(e -> e > 50);
TECHNOLOGY
DIVISION
list.stream().map(Object::toString).collect(Collectors.toList())
;
Integer result =
list.stream().reduce(3,
Integer::sum);
7
Java 8 Streams
TECHNOLOGY
DIVISION
TECHNOLOGY
DIVISION
TECHNOLOGY
DIVISION
Java 8
GS Collections
Functional Interfaces
46
298
11
75
309
47
109
48 x 3 = 144
38 x 8 = 304
10
TECHNOLOGY
DIVISION
flatCollect
partition
makeString / appendString
groupBy
aggregateBy
sumOf
sumBy
11
Futility of Utility
TECHNOLOGY
DIVISION
Utility
Easy to extend with new behaviors without breaking existing
clients
API
Easy to discover new features
Easy to optimize
Easy to read from left to right
Return types are specific and easy to understand
Verb vs. gerund
12
TECHNOLOGY
DIVISION
13
TECHNOLOGY
DIVISION
14
TECHNOLOGY
DIVISION
15
TECHNOLOGY
DIVISION
16
TECHNOLOGY
DIVISION
17
TECHNOLOGY
DIVISION
18
Agenda
TECHNOLOGY
DIVISION
Introductions
Lost and Found
Streams
The Iceberg
APIs
Fluency
Memory Efficiency
Method references are awesome
Framework Comparisons
19
Anagram tutorial
TECHNOLOGY
DIVISION
http://docs.oracle.com/javase/tutorial/collections/algorithms /
Start with all words in the dictionary
Group them by their alphagrams
Alphagram contains sorted characters
alerts aelrst
stelar aelrst
20
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.stream()
.collect(Collectors.groupingBy(Alphagram::new))
.values()
.stream()
.filter(each -> each.size() >= SIZE_THRESHOLD)
.sorted(Comparator.<List<?
>>comparingInt(List::size).reversed())
.map(each -> each.size() + ": " + each)
.forEach(System.out::println);
21
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
22
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Type: RichIterable<RichIterable<String>>
24
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Type: RichIterable<RichIterable<String>>
25
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Type: MutableList<RichIterable<String>>
26
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Type: LazyIterable<RichIterable<String>>
27
Anagram tutorial
TECHNOLOGY
DIVISION
this.getWords()
.groupBy(Alphagram::new)
.multiValuesView()
.select(each -> each.size() >= SIZE_THRESHOLD)
.toSortedListBy(RichIterable::size)
.asReversed()
.collect(each -> each.size() + ": " + each)
.each(System.out::println);
Type: LazyIterable<String>
28
TECHNOLOGY
DIVISION
Stream<Address> addresses =
people.parallelStream()
.map(Person::getAddress);
ParallelListIterable<Address> addresses =
people.asParallel(executor, batchSize)
.collect(Person::getAddress);
http://www.infoq.com/presentations/java-streams-scala-parallel-collections
29
Agenda
TECHNOLOGY
DIVISION
Introductions
Lost and Found
Streams
The Iceberg
APIs
Fluency
Memory Efficiency
Method references are awesome
Framework Comparisons
30
Comparing Maps
TECHNOLOGY
DIVISION
45000000
40000000
35000000
JDK
HashMap
30000000
GSC
UnifedMap
25000000
Trove
THashMap
20000000
Size
(Mb)
15000000
10000000
5000000
0
Elements
31
Memory Optimizations
TECHNOLOGY
DIVISION
32
Comparing Sets
TECHNOLOGY
DIVISION
60,000,000
50,000,000
JDK
HashSet
40,000,000
GSC
UnifedSet
30,000,000
Trove
THashSet
Size (Mb)
20,000,000
10,000,000
Elements
33
Memory Optimizations
TECHNOLOGY
DIVISION
34
TECHNOLOGY
DIVISION
35
TECHNOLOGY
DIVISION
25,000,000
20,000,000
15,000,000
Size (Mb)
10,000,000
JDK
ArrayList
GSC
IntArrayList
Trove
TIntArrayLis
t
5,000,000
Elements
36
TECHNOLOGY
DIVISION
37
Agenda
TECHNOLOGY
DIVISION
Introductions
Lost and Found
Streams
The Iceberg
APIs
Fluency
Memory Efficiency
Method references are awesome
Framework Comparisons
38
TECHNOLOGY
DIVISION
39
TECHNOLOGY
DIVISION
40
TECHNOLOGY
DIVISION
41
TECHNOLOGY
DIVISION
42
TECHNOLOGY
DIVISION
43
TECHNOLOGY
DIVISION
44
Framework Comparisons
Features
GS Collections
Java 8
Guava
Rich API
Interfaces
Readable,
Mutable,
Immutable,
FixedSize, Lazy
Mutable,
Stream
Mutable,
Fluent
(+Bag)
Immutable Collections
Primitive Collections
(+Bag,
+Immutable)
Multimaps
(+Bag,
+SortedBag)
(+Linked)
Bags (Multisets)
BiMaps
Iteration Styles
Eager/Lazy,
Trove
TECHNOLOGY
DIVISION
Scala
Mutable
Readable,
Mutable,
Immutable, Lazy
Lazy,
Lazy,
(Multimap trait)
Eager,
Eager/Lazy,
45
Resources
TECHNOLOGY
DIVISION
GS Collections on GitHub
https://github.com/goldmansachs/gs-collections
https://github.com/goldmansachs/gs-collections/wiki
https://github.com/goldmansachs/gs-collections-kata
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
46
TECHNOLOGY
DIVISION
2014 Goldman Sachs. This presentation should not be relied upon or considered investment advice. Goldman Sachs does not warrant or guarantee to anyone the accuracy, completeness or efficacy of this
presentation, and recipients should not rely on it except at their own risk. This presentation may not be forwarded or disclosed except with this disclaimer intact.
47