SlideShare a Scribd company logo
Collections.compare(() -> {
JDK; Apache; Eclipse; Guava...});
Nikhil J. Nanivadekar
#CollectionsCompare #GIDS17 @NikhilNanivade
Agenda
1. Introduction
2. History of Java util collections framework
3. Gaps in use cases from the timeline
4. Timeline with other collection frameworks
5. Use case, domain diagrams
6. Deep dive in use case
7. Memory characteristics
#CollectionsCompare #GIDS17 @NikhilNanivade
Authors
• Donald Raab (@TheDonRaab)
• Leonardo Lima (@leomrlima)
• Nikhil J. Nanivadekar (@NikhilNanivade)
#CollectionsCompare #GIDS17 @NikhilNanivade
Speaker
Nikhil J. Nanivadekar
– Mechanical Engineer
– Software developer
– Vice President, Technology at Goldman Sachs
– From Pune, Maharashtra currently in Salt Lake City,
Utah
java.util Collections
#CollectionsCompare #GIDS17 @NikhilNanivade
java.util Collections
• Java Collection Framework has been around since
1998/JDK 1.2. Very basic but critical collection
support for Java.
• Interfaces: Maps and Collections (List, Set,
Queue, Deque)
• Implementations: Basic and Concurrent versions
of the interfaces, sorted and concurrent as well
• Algorithms: Sorting, Shuffling, Routine Data
Manipulation, Searching, Composition
• Best way to get started is using the simple and
concurrent tutorials
#CollectionsCompare #GIDS17 @NikhilNanivade
Java Collections Frameworks
Java 2
1998
• Interfaces
• Collection
• List
• Set
• Map
• SortedSet
• SortedMap
Java 5
2005
• Generics
• For-each loop
• Interfaces
• Iterable
• Queue
• ConcurrentMap
• BlockingQueue
Java 6
2006
•Interfaces
•NavigableSet
•NavigableMap
•Deque
•BlockingDeque
•ConcurrentNavigableMap
Java 7
2011
• Interfaces
• TransferQueue
Java 8
2014
• Lambdas
• Method Refs
• Default Methods
• Interfaces
• BaseStream
• Stream
• IntStream
• LongStream
• DoubleStream
• Collector
• Spliterator
• PrimitiveIterator
!java.util Collections?
#CollectionsCompare #GIDS17 @NikhilNanivade
!java.util Collections
• We’re considering 4 collection frameworks, in
alphabetical order:
• Apache Commons Collection
– version 4.1
• Eclipse Collections (Formerly GS Collections)
– version 8.1.0
• Google Guava
– version 21.0
• Javaslang (now called Vavr)
– version 2.1.0-alpha
#CollectionsCompare #GIDS17 @NikhilNanivade
Collection Framework Timelines
Java 2
1998
•Jakarta
Collections 1.0
•2001
•Apache Collections
3.0
•2004
Java 6
2006
•Google Collections
1.0
•Dec. 2009
Java 7
2011
•Google Guava 10.0
•Sept. 2011
•GS Collections 1.0
•Jan. 2012
•Apache Collections
4.0
•Nov. 2013
Java 8
2014
•Javaslang 1.0
•Mar. 2014
•Apache Collections 4.1
•Nov. 2015
•Eclipse Collections 7.0
•Jan. 2016
•Eclipse Collections 8.0
(Java 8)
•Sept. 2016
•Google Guava 20.0
•Oct. 2016
•Javaslang 2.1a
•Nov. 2016
March
2017
•Google Guava 21.0
(Java 8)
•Jan. 2017
•Eclipse Collections
8.1
•Mar. 2017
Collections.compare();
#CollectionsCompare #GIDS17 @NikhilNanivade
Use Case – Deck of Cards
The Collections Compare Project: https://github.com/nikhilnanivadekar/CollectionsCompare
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Benchmarks
• JMH – Java Microbenchmark Harness
• http://openjdk.java.net/projects/code-tools/jmh/
• Measure Reported – Operations per second
• Bigger numbers are better
• 4 Core Intel I7, 50 Warm-up iterations, 30
measurement iterations, two forks
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deck of Cards
102,037
79,343 76,982
56,224
91,017
0
20,000
40,000
60,000
80,000
100,000
120,000
Scoreops/s
Framework
Deck of Cards
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
A Deck of Cards – Only the Types
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, SortedSet<Card>> cardsBySuit;
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Shared Code – Cartesian Product
public static Stream<Card> streamCards() {
return Card.cartesianProduct(
EnumSet.allOf(Rank.class),
EnumSet.allOf(Suit.class),
Card::new);
}
private static <A, B, C> Stream<C> cartesianProduct(
Set<A> set1,
Set<B> set2,
Function2<A, B, C> function) {
return set1.stream().flatMap(first ->
set2.stream().map(second ->
function.apply(first, second)));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Cartesian Product
185,087
203,660
465,999
127,439 114,634
0
50,000
100,000
150,000
200,000
250,000
300,000
350,000
400,000
450,000
500,000
Scoreops/s
Framework
Cartesian Product
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Cartesian Product
public class JDK8DeckOfCards {
private SortedSet<Card> cards;
public JDK8DeckOfCards() {
this.cards = Card.streamCards()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Cartesian Product
public class ApacheCommonsDeckOfCards {
private SortedSet<Card> cards;
public ApacheCommonsDeckOfCards() {
this.cards = Card.streamCards()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Cartesian Product
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSet<Card> cards;
public EclipseCollectionsDeckOfCards() {
this.cards = SortedSets.immutable.with(
Card.streamCards()
.toArray(Card[]::new));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Cartesian Product
public class GoogleGuavaDeckOfCards {
private ImmutableSortedSet<Card> cards;
public GoogleGuavaDeckOfCards() {
this.cards = Card.streamCards()
.collect(ImmutableSortedSet
.toImmutableSortedSet(
Comparator.naturalOrder()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Cartesian Product
public class JavaSlangDeckOfCards {
private SortedSet<Card> cards;
public JavaSlangDeckOfCards() {
this.cards = Card.streamCards()
.collect(TreeSet.collector());
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - groupBy
540,396
183,848
231,321
176,412
353,651
-
100,000
200,000
300,000
400,000
500,000
600,000
Scoreops/s
Framework
groupBy
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Group By
public class JDK8DeckOfCards {
private Map<Suit, SortedSet<Card>> cardsBySuit;
public JDK8DeckOfCards() {
this.cardsBySuit =
Collections.unmodifiableMap(
this.cards.stream()
.collect(Collectors.groupingBy(
Card::getSuit,
Collectors.mapping(
Function.identity(),
Collectors.collectingAndThen(
Collectors.toCollection(TreeSet::new),
Collections::unmodifiableSortedSet)))));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Group By
public class ApacheCommonsDeckOfCards {
private MultiValuedMap<Suit, Card> cardsBySuit;
public ApacheCommonsDeckOfCards() {
SetValuedMap<Suit, Card> cbs =
MultiMapUtils.newSetValuedHashMap();
this.cards.forEach(card ->
cbs.put(card.getSuit(), card));
this.cardsBySuit =
MultiMapUtils.unmodifiableMultiValuedMap(cbs);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Group By
public class EclipseCollectionsDeckOfCards {
private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit;
public EclipseCollectionsDeckOfCards() {
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Group By
public class GoogleGuavaDeckOfCards {
private ImmutableSetMultimap<Suit, Card> cardsBySuit;
public GoogleGuavaDeckOfCards() {
ImmutableSetMultimap.Builder<Suit, Card> builder =
new ImmutableSetMultimap.Builder<Suit, Card>()
.orderValuesBy(Comparator.naturalOrder());
this.cards.forEach(card ->
builder.put(card.getSuit(), card));
this.cardsBySuit = builder.build();
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Group By
public class JavaSlangDeckOfCards {
private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
public JavaSlangDeckOfCards() {
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deck of Cards
102,037
79,343 76,982
56,224
91,017
0
20,000
40,000
60,000
80,000
100,000
120,000
Scoreops/s
Framework
Deck of Cards
Apache EC Guava Javaslang JDK
540,396
183,848231,321176,412
353,651
-
500,000
1,000,000
Scoreops/s Framework
groupBy
Apache EC Guava Javaslang JDK
185,087 203,660
465,999
127,439 114,634
0
200,000
400,000
600,000
Scoreops/s
Framework
Cartesian Product
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of five
cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - countsBySuit
706,272
1,096,527
533,728
440,786
724,526
0
200,000
400,000
600,000
800,000
1,000,000
1,200,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test - countsByRank
539,252
827,986
444,832
390,134
591,869
0
100,000
200,000
300,000
400,000
500,000
600,000
700,000
800,000
900,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Count By
public Map<Suit, Long> countsBySuit() {
return this.cards.stream()
.collect(Collectors.groupingBy(
Card::getSuit, Collectors.counting()));
}
public Map<Rank, Long> countsByRank() {
return this.cards.stream()
.collect(Collectors.groupingBy(
Card::getRank, Collectors.counting()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Count By
public Bag<Suit> countsBySuit() {
return this.cards.stream()
.map(Card::getSuit)
.collect(Collectors.toCollection(HashBag::new));
}
public MultiSet<Rank> countsByRank() {
return this.cards.stream()
.map(Card::getRank)
.collect(Collectors.toCollection(
HashMultiSet::new));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Count By
public Bag<Suit> countsBySuit() {
return this.cards.asLazy()
.collect(Card::getSuit)
.toBag();
}
public Bag<Rank> countsByRank() {
return this.cards.asLazy()
.collect(Card::getRank)
.toBag();
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Count By
public Multiset<Suit> countsBySuit() {
return this.cards.stream()
.map(Card::getSuit)
.collect(Collectors.toCollection(
HashMultiset::create));
}
public Multiset<Rank> countsByRank() {
return this.cards.stream()
.map(Card::getRank)
.collect(Collectors.toCollection(
HashMultiset::create));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Count By
public java.util.Map<Suit, Long> countsBySuit() {
return this.cards.collect(
Collectors.groupingBy(
Card::getSuit,
Collectors.counting()));
}
public java.util.Map<Rank, Long> countsByRank() {
return this.cards.collect(
Collectors.groupingBy(
Card::getRank,
Collectors.counting()));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Problem Statement – Deck of Cards
1. Create Deck of Cards
– Store Cards in an “Immutable” SortedSet
(Cartesian product of Suit x Rank)
– Group the cards by Suit in an “Immutable” SortedSet
“Multimap” (Group By)
2. Get the number of cards
– Count By Suit returning “Multiset” or “Bag”
– Count By Rank returning “Multiset” or “Bag”
3. Deal five hands of five cards each
– Return the cards as an “Immutable” List of five Sets of
five cards
#CollectionsCompare #GIDS17 @NikhilNanivade
Performance Test – Deal Hands
291,488
502,448
305,673
372,466
300,975
0
100,000
200,000
300,000
400,000
500,000
600,000
Scoreops/s
Framework
Apache EC Guava Javaslang JDK
#CollectionsCompare #GIDS17 @NikhilNanivade
JDK Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Apache Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Eclipse Collections – Deal Hands
public ImmutableList<Set<Card>> dealHands(
MutableStack<Card> shuffled,
int hands,
int cardsPerHand) {
return IntInterval.oneTo(hands)
.collect(i ->
this.deal(shuffled, cardsPerHand));
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Google Guava – Deal Hands
public ImmutableList<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand) {
return IntStream.range(0, hands)
.mapToObj(i ->
this.deal(shuffled, cardsPerHand))
.collect(ImmutableList.toImmutableList());
}
#CollectionsCompare #GIDS17 @NikhilNanivade
Javaslang – Deal Hands
public List<Set<Card>> dealHands(
Stack<Card> shuffled,
int hands,
int cardsPerHand) {
List<Set<Card>> list = List.empty();
for (int i = 0; i < hands; i++) {
Tuple2<Set<Card>, ? extends Stack<Card>> tuple2 =
this.deal(shuffled, cardsPerHand);
shuffled = tuple2._2();
list = list.append(tuple2._1());
}
return list;
}
Memory Benchmarks
#CollectionsCompare #GIDS17 @NikhilNanivade
Memory Benchmarks
• ObjectExplorer, by Dimitris Andrew
• Open Source under Apache License 2.0
• Measure Reported –
– Memory (Kb) vs Size
– Memory (Kb) vs List, Set, Map with 1,000,000 elements
• Smaller the better
Sources
– GitHub:
https://github.com/DimitrisAndreou/memory-measurer
– Found from StackOverflow:
http://stackoverflow.com/a/9368930/5182052
#CollectionsCompare #GIDS17 @NikhilNanivade
List<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
List<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Set<String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<Integer, Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<Integer, Integer>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<String, String>
#CollectionsCompare #GIDS17 @NikhilNanivade
Map<String, String>
Summary
#CollectionsCompare #GIDS17 @NikhilNanivade
Link
• The Collections Compare Project
https://github.com/nikhilnanivadekar/CollectionsCompare
#CollectionsCompare #GIDS17 @NikhilNanivade
Collection Framework Comparison
Feature JDK Apache Guava Eclipse Javaslang 1st, 2nd, 3rd
List, Set, Map ✔  ✖ ✔  JDK, EC, JS
Multiset / Bag ✖ ✔ ✔ ✔ ✖ GG, EC, AC
Multimap ✖ ✔ ✔ ✔ ✔ GG, EC, AC
BiMap ✖ ✔ ✔ ✔ ✖ GG, EC, AC
Stack ✔  ✖ ✔ ✔ EC, JDK, JS
Tree / Trie ✖ ✔ ✖ ✖ ✔ JS, AC
Table ✖ ✖ ✔ ✖ ✖ GG
Additional Types ✔ ✔ ✔   AC, JDK, GG
Immutable? ✖ ✖ ✔ ✔ ✔ JS, EC, GG
Primitives?  ✖  ✔ ✖ EC, JDK, GG
Fluent API    ✔ ✔ EC, JS, JDK
(E), (L), (S), (P)* , ✔, ✔, ✔ , , ✔, ✖ ✖, , ✔, ✖ ✔, ✔, ✔, ✔ ✔, ✔, ✔, ✖ EC, JDK, JS
Thanks!
The Collections Compare Project
https://github.com/nikhilnanivadekar/CollectionsCompare

More Related Content

Similar to Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017

10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
Payara
 
jCardSim - development platform for Java Card Applications
jCardSim - development platform for Java Card ApplicationsjCardSim - development platform for Java Card Applications
jCardSim - development platform for Java Card Applications
Mikhail Dudarev
 
The cost of learning - advantage of mixer2
The cost of learning - advantage of mixer2The cost of learning - advantage of mixer2
The cost of learning - advantage of mixer2
Y Watanabe
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
Peter Pilgrim
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules upload
Ryan Cuprak
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化Tomoharu ASAMI
 
Apache spark core
Apache spark coreApache spark core
Apache spark core
Thành Nguyễn
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
takezoe
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Mihail Stoynov
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS偉格 高
 
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
PgDay.Seoul
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Ovadiah Myrgorod
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
台灣資料科學年會
 
Packing for the Web with Webpack
Packing for the Web with WebpackPacking for the Web with Webpack
Packing for the Web with Webpack
Thiago Temple
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
GWTcon
 
Webpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of usWebpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of us
Stefan Adolf
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
Elizabeth Smith
 
S313431 JPA 2.0 Overview
S313431 JPA 2.0 OverviewS313431 JPA 2.0 Overview
S313431 JPA 2.0 Overview
Ludovic Champenois
 

Similar to Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017 (20)

10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
10 Strategies for Developing Reliable Jakarta EE & MicroProfile Applications ...
 
jCardSim - development platform for Java Card Applications
jCardSim - development platform for Java Card ApplicationsjCardSim - development platform for Java Card Applications
jCardSim - development platform for Java Card Applications
 
The cost of learning - advantage of mixer2
The cost of learning - advantage of mixer2The cost of learning - advantage of mixer2
The cost of learning - advantage of mixer2
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules upload
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化
 
Apache spark core
Apache spark coreApache spark core
Apache spark core
 
Scala Frustrations
Scala FrustrationsScala Frustrations
Scala Frustrations
 
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)
 
Module, AMD, RequireJS
Module, AMD, RequireJSModule, AMD, RequireJS
Module, AMD, RequireJS
 
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
 
Backbone js-slides
Backbone js-slidesBackbone js-slides
Backbone js-slides
 
Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8Using Backbone.js with Drupal 7 and 8
Using Backbone.js with Drupal 7 and 8
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
 
Packing for the Web with Webpack
Packing for the Web with WebpackPacking for the Web with Webpack
Packing for the Web with Webpack
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
Webpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of usWebpack Encore - Asset Management for the rest of us
Webpack Encore - Asset Management for the rest of us
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
S313431 JPA 2.0 Overview
S313431 JPA 2.0 OverviewS313431 JPA 2.0 Overview
S313431 JPA 2.0 Overview
 

Recently uploaded

Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
nkrafacyberclub
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 

Recently uploaded (20)

Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptxSecstrike : Reverse Engineering & Pwnable tools for CTF.pptx
Secstrike : Reverse Engineering & Pwnable tools for CTF.pptx
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 

Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017

  • 1. Collections.compare(() -> { JDK; Apache; Eclipse; Guava...}); Nikhil J. Nanivadekar
  • 2. #CollectionsCompare #GIDS17 @NikhilNanivade Agenda 1. Introduction 2. History of Java util collections framework 3. Gaps in use cases from the timeline 4. Timeline with other collection frameworks 5. Use case, domain diagrams 6. Deep dive in use case 7. Memory characteristics
  • 3. #CollectionsCompare #GIDS17 @NikhilNanivade Authors • Donald Raab (@TheDonRaab) • Leonardo Lima (@leomrlima) • Nikhil J. Nanivadekar (@NikhilNanivade)
  • 4. #CollectionsCompare #GIDS17 @NikhilNanivade Speaker Nikhil J. Nanivadekar – Mechanical Engineer – Software developer – Vice President, Technology at Goldman Sachs – From Pune, Maharashtra currently in Salt Lake City, Utah
  • 6. #CollectionsCompare #GIDS17 @NikhilNanivade java.util Collections • Java Collection Framework has been around since 1998/JDK 1.2. Very basic but critical collection support for Java. • Interfaces: Maps and Collections (List, Set, Queue, Deque) • Implementations: Basic and Concurrent versions of the interfaces, sorted and concurrent as well • Algorithms: Sorting, Shuffling, Routine Data Manipulation, Searching, Composition • Best way to get started is using the simple and concurrent tutorials
  • 7. #CollectionsCompare #GIDS17 @NikhilNanivade Java Collections Frameworks Java 2 1998 • Interfaces • Collection • List • Set • Map • SortedSet • SortedMap Java 5 2005 • Generics • For-each loop • Interfaces • Iterable • Queue • ConcurrentMap • BlockingQueue Java 6 2006 •Interfaces •NavigableSet •NavigableMap •Deque •BlockingDeque •ConcurrentNavigableMap Java 7 2011 • Interfaces • TransferQueue Java 8 2014 • Lambdas • Method Refs • Default Methods • Interfaces • BaseStream • Stream • IntStream • LongStream • DoubleStream • Collector • Spliterator • PrimitiveIterator
  • 9. #CollectionsCompare #GIDS17 @NikhilNanivade !java.util Collections • We’re considering 4 collection frameworks, in alphabetical order: • Apache Commons Collection – version 4.1 • Eclipse Collections (Formerly GS Collections) – version 8.1.0 • Google Guava – version 21.0 • Javaslang (now called Vavr) – version 2.1.0-alpha
  • 10. #CollectionsCompare #GIDS17 @NikhilNanivade Collection Framework Timelines Java 2 1998 •Jakarta Collections 1.0 •2001 •Apache Collections 3.0 •2004 Java 6 2006 •Google Collections 1.0 •Dec. 2009 Java 7 2011 •Google Guava 10.0 •Sept. 2011 •GS Collections 1.0 •Jan. 2012 •Apache Collections 4.0 •Nov. 2013 Java 8 2014 •Javaslang 1.0 •Mar. 2014 •Apache Collections 4.1 •Nov. 2015 •Eclipse Collections 7.0 •Jan. 2016 •Eclipse Collections 8.0 (Java 8) •Sept. 2016 •Google Guava 20.0 •Oct. 2016 •Javaslang 2.1a •Nov. 2016 March 2017 •Google Guava 21.0 (Java 8) •Jan. 2017 •Eclipse Collections 8.1 •Mar. 2017
  • 12. #CollectionsCompare #GIDS17 @NikhilNanivade Use Case – Deck of Cards The Collections Compare Project: https://github.com/nikhilnanivadekar/CollectionsCompare
  • 13. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 14. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Benchmarks • JMH – Java Microbenchmark Harness • http://openjdk.java.net/projects/code-tools/jmh/ • Measure Reported – Operations per second • Bigger numbers are better • 4 Core Intel I7, 50 Warm-up iterations, 30 measurement iterations, two forks
  • 15. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 16. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test – Deck of Cards 102,037 79,343 76,982 56,224 91,017 0 20,000 40,000 60,000 80,000 100,000 120,000 Scoreops/s Framework Deck of Cards Apache EC Guava Javaslang JDK
  • 17. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 18. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 19. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 20. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 21. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 22. #CollectionsCompare #GIDS17 @NikhilNanivade A Deck of Cards – Only the Types public class JDK8DeckOfCards { private SortedSet<Card> cards; private Map<Suit, SortedSet<Card>> cardsBySuit; public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; private MultiValuedMap<Suit, Card> cardsBySuit; public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; private ImmutableSetMultimap<Suit, Card> cardsBySuit; public class JavaSlangDeckOfCards { private SortedSet<Card> cards; private Map<Suit, ? extends SortedSet<Card>> cardsBySuit;
  • 23. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 24. #CollectionsCompare #GIDS17 @NikhilNanivade Shared Code – Cartesian Product public static Stream<Card> streamCards() { return Card.cartesianProduct( EnumSet.allOf(Rank.class), EnumSet.allOf(Suit.class), Card::new); } private static <A, B, C> Stream<C> cartesianProduct( Set<A> set1, Set<B> set2, Function2<A, B, C> function) { return set1.stream().flatMap(first -> set2.stream().map(second -> function.apply(first, second))); }
  • 25. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test – Cartesian Product 185,087 203,660 465,999 127,439 114,634 0 50,000 100,000 150,000 200,000 250,000 300,000 350,000 400,000 450,000 500,000 Scoreops/s Framework Cartesian Product Apache EC Guava Javaslang JDK
  • 26. #CollectionsCompare #GIDS17 @NikhilNanivade JDK Collections – Cartesian Product public class JDK8DeckOfCards { private SortedSet<Card> cards; public JDK8DeckOfCards() { this.cards = Card.streamCards() .collect(Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet)); }
  • 27. #CollectionsCompare #GIDS17 @NikhilNanivade Apache Collections – Cartesian Product public class ApacheCommonsDeckOfCards { private SortedSet<Card> cards; public ApacheCommonsDeckOfCards() { this.cards = Card.streamCards() .collect(Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet)); }
  • 28. #CollectionsCompare #GIDS17 @NikhilNanivade Eclipse Collections – Cartesian Product public class EclipseCollectionsDeckOfCards { private ImmutableSortedSet<Card> cards; public EclipseCollectionsDeckOfCards() { this.cards = SortedSets.immutable.with( Card.streamCards() .toArray(Card[]::new)); }
  • 29. #CollectionsCompare #GIDS17 @NikhilNanivade Google Guava – Cartesian Product public class GoogleGuavaDeckOfCards { private ImmutableSortedSet<Card> cards; public GoogleGuavaDeckOfCards() { this.cards = Card.streamCards() .collect(ImmutableSortedSet .toImmutableSortedSet( Comparator.naturalOrder())); }
  • 30. #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang – Cartesian Product public class JavaSlangDeckOfCards { private SortedSet<Card> cards; public JavaSlangDeckOfCards() { this.cards = Card.streamCards() .collect(TreeSet.collector()); }
  • 31. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 32. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test - groupBy 540,396 183,848 231,321 176,412 353,651 - 100,000 200,000 300,000 400,000 500,000 600,000 Scoreops/s Framework groupBy Apache EC Guava Javaslang JDK
  • 33. #CollectionsCompare #GIDS17 @NikhilNanivade JDK Collections – Group By public class JDK8DeckOfCards { private Map<Suit, SortedSet<Card>> cardsBySuit; public JDK8DeckOfCards() { this.cardsBySuit = Collections.unmodifiableMap( this.cards.stream() .collect(Collectors.groupingBy( Card::getSuit, Collectors.mapping( Function.identity(), Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), Collections::unmodifiableSortedSet))))); }
  • 34. #CollectionsCompare #GIDS17 @NikhilNanivade Apache Collections – Group By public class ApacheCommonsDeckOfCards { private MultiValuedMap<Suit, Card> cardsBySuit; public ApacheCommonsDeckOfCards() { SetValuedMap<Suit, Card> cbs = MultiMapUtils.newSetValuedHashMap(); this.cards.forEach(card -> cbs.put(card.getSuit(), card)); this.cardsBySuit = MultiMapUtils.unmodifiableMultiValuedMap(cbs); }
  • 35. #CollectionsCompare #GIDS17 @NikhilNanivade Eclipse Collections – Group By public class EclipseCollectionsDeckOfCards { private ImmutableSortedSetMultimap<Suit, Card> cardsBySuit; public EclipseCollectionsDeckOfCards() { this.cardsBySuit = this.cards.groupBy(Card::getSuit); }
  • 36. #CollectionsCompare #GIDS17 @NikhilNanivade Google Guava – Group By public class GoogleGuavaDeckOfCards { private ImmutableSetMultimap<Suit, Card> cardsBySuit; public GoogleGuavaDeckOfCards() { ImmutableSetMultimap.Builder<Suit, Card> builder = new ImmutableSetMultimap.Builder<Suit, Card>() .orderValuesBy(Comparator.naturalOrder()); this.cards.forEach(card -> builder.put(card.getSuit(), card)); this.cardsBySuit = builder.build(); }
  • 37. #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang – Group By public class JavaSlangDeckOfCards { private Map<Suit, ? extends SortedSet<Card>> cardsBySuit; public JavaSlangDeckOfCards() { this.cardsBySuit = this.cards.groupBy(Card::getSuit); }
  • 38. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test – Deck of Cards 102,037 79,343 76,982 56,224 91,017 0 20,000 40,000 60,000 80,000 100,000 120,000 Scoreops/s Framework Deck of Cards Apache EC Guava Javaslang JDK 540,396 183,848231,321176,412 353,651 - 500,000 1,000,000 Scoreops/s Framework groupBy Apache EC Guava Javaslang JDK 185,087 203,660 465,999 127,439 114,634 0 200,000 400,000 600,000 Scoreops/s Framework Cartesian Product Apache EC Guava Javaslang JDK
  • 39. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 40. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test - countsBySuit 706,272 1,096,527 533,728 440,786 724,526 0 200,000 400,000 600,000 800,000 1,000,000 1,200,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 41. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test - countsByRank 539,252 827,986 444,832 390,134 591,869 0 100,000 200,000 300,000 400,000 500,000 600,000 700,000 800,000 900,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 42. #CollectionsCompare #GIDS17 @NikhilNanivade JDK Collections – Count By public Map<Suit, Long> countsBySuit() { return this.cards.stream() .collect(Collectors.groupingBy( Card::getSuit, Collectors.counting())); } public Map<Rank, Long> countsByRank() { return this.cards.stream() .collect(Collectors.groupingBy( Card::getRank, Collectors.counting())); }
  • 43. #CollectionsCompare #GIDS17 @NikhilNanivade Apache Collections – Count By public Bag<Suit> countsBySuit() { return this.cards.stream() .map(Card::getSuit) .collect(Collectors.toCollection(HashBag::new)); } public MultiSet<Rank> countsByRank() { return this.cards.stream() .map(Card::getRank) .collect(Collectors.toCollection( HashMultiSet::new)); }
  • 44. #CollectionsCompare #GIDS17 @NikhilNanivade Eclipse Collections – Count By public Bag<Suit> countsBySuit() { return this.cards.asLazy() .collect(Card::getSuit) .toBag(); } public Bag<Rank> countsByRank() { return this.cards.asLazy() .collect(Card::getRank) .toBag(); }
  • 45. #CollectionsCompare #GIDS17 @NikhilNanivade Google Guava – Count By public Multiset<Suit> countsBySuit() { return this.cards.stream() .map(Card::getSuit) .collect(Collectors.toCollection( HashMultiset::create)); } public Multiset<Rank> countsByRank() { return this.cards.stream() .map(Card::getRank) .collect(Collectors.toCollection( HashMultiset::create)); }
  • 46. #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang – Count By public java.util.Map<Suit, Long> countsBySuit() { return this.cards.collect( Collectors.groupingBy( Card::getSuit, Collectors.counting())); } public java.util.Map<Rank, Long> countsByRank() { return this.cards.collect( Collectors.groupingBy( Card::getRank, Collectors.counting())); }
  • 47. #CollectionsCompare #GIDS17 @NikhilNanivade Problem Statement – Deck of Cards 1. Create Deck of Cards – Store Cards in an “Immutable” SortedSet (Cartesian product of Suit x Rank) – Group the cards by Suit in an “Immutable” SortedSet “Multimap” (Group By) 2. Get the number of cards – Count By Suit returning “Multiset” or “Bag” – Count By Rank returning “Multiset” or “Bag” 3. Deal five hands of five cards each – Return the cards as an “Immutable” List of five Sets of five cards
  • 48. #CollectionsCompare #GIDS17 @NikhilNanivade Performance Test – Deal Hands 291,488 502,448 305,673 372,466 300,975 0 100,000 200,000 300,000 400,000 500,000 600,000 Scoreops/s Framework Apache EC Guava Javaslang JDK
  • 49. #CollectionsCompare #GIDS17 @NikhilNanivade JDK Collections – Deal Hands public List<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList)); }
  • 50. #CollectionsCompare #GIDS17 @NikhilNanivade Apache Collections – Deal Hands public List<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList)); }
  • 51. #CollectionsCompare #GIDS17 @NikhilNanivade Eclipse Collections – Deal Hands public ImmutableList<Set<Card>> dealHands( MutableStack<Card> shuffled, int hands, int cardsPerHand) { return IntInterval.oneTo(hands) .collect(i -> this.deal(shuffled, cardsPerHand)); }
  • 52. #CollectionsCompare #GIDS17 @NikhilNanivade Google Guava – Deal Hands public ImmutableList<Set<Card>> dealHands( Deque<Card> shuffled, int hands, int cardsPerHand) { return IntStream.range(0, hands) .mapToObj(i -> this.deal(shuffled, cardsPerHand)) .collect(ImmutableList.toImmutableList()); }
  • 53. #CollectionsCompare #GIDS17 @NikhilNanivade Javaslang – Deal Hands public List<Set<Card>> dealHands( Stack<Card> shuffled, int hands, int cardsPerHand) { List<Set<Card>> list = List.empty(); for (int i = 0; i < hands; i++) { Tuple2<Set<Card>, ? extends Stack<Card>> tuple2 = this.deal(shuffled, cardsPerHand); shuffled = tuple2._2(); list = list.append(tuple2._1()); } return list; }
  • 55. #CollectionsCompare #GIDS17 @NikhilNanivade Memory Benchmarks • ObjectExplorer, by Dimitris Andrew • Open Source under Apache License 2.0 • Measure Reported – – Memory (Kb) vs Size – Memory (Kb) vs List, Set, Map with 1,000,000 elements • Smaller the better Sources – GitHub: https://github.com/DimitrisAndreou/memory-measurer – Found from StackOverflow: http://stackoverflow.com/a/9368930/5182052
  • 69. #CollectionsCompare #GIDS17 @NikhilNanivade Link • The Collections Compare Project https://github.com/nikhilnanivadekar/CollectionsCompare
  • 70. #CollectionsCompare #GIDS17 @NikhilNanivade Collection Framework Comparison Feature JDK Apache Guava Eclipse Javaslang 1st, 2nd, 3rd List, Set, Map ✔  ✖ ✔  JDK, EC, JS Multiset / Bag ✖ ✔ ✔ ✔ ✖ GG, EC, AC Multimap ✖ ✔ ✔ ✔ ✔ GG, EC, AC BiMap ✖ ✔ ✔ ✔ ✖ GG, EC, AC Stack ✔  ✖ ✔ ✔ EC, JDK, JS Tree / Trie ✖ ✔ ✖ ✖ ✔ JS, AC Table ✖ ✖ ✔ ✖ ✖ GG Additional Types ✔ ✔ ✔   AC, JDK, GG Immutable? ✖ ✖ ✔ ✔ ✔ JS, EC, GG Primitives?  ✖  ✔ ✖ EC, JDK, GG Fluent API    ✔ ✔ EC, JS, JDK (E), (L), (S), (P)* , ✔, ✔, ✔ , , ✔, ✖ ✖, , ✔, ✖ ✔, ✔, ✔, ✔ ✔, ✔, ✔, ✖ EC, JDK, JS
  • 71. Thanks! The Collections Compare Project https://github.com/nikhilnanivadekar/CollectionsCompare