SlideShare a Scribd company logo
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Collections.compare(() -> {
JDK; Apache; Eclipse; Guava...});
Donald Raab
Leonardo Lima
Nikhil J. Nanivadekar
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
java.util.Collections
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Java 2
1998
• Interfaces
• Collection
• List
• Set
• Map
• List
• SortedMap
Java 5
2005
• Generics
• For-each loop
• Interfaces
• Iterable
• Queue
• ConcurrentMa
p
• BlockingQueu
e
Java 6
2006
•Interfaces
•NavigableSet
•NavigableMap
•Deque
•BlockingDeque
•ConcurrentNavigableM
ap
Java 7
2011
• Interfaces
• TransferQue
ue
Java 8
2014
• Lambdas
• Method Refs
• Default Methods
• Interfaces
• BaseStream
• Stream
• IntStream
• LongStream
• DoubleStream
• Collector
• Spliterator
• PrimitiveIterator
Java 9
2017
• JPMS
• Collection
Factory
methods
• New Stream
APIs
• Improved
Javadoc
• Private
interface
methods
Java Collections Framework
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
!java.util.Collections?
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
!java.util Collections
 We’re comparing 4 other collection
frameworks, and JDK 8 Collections. In
alphabetical order:
 Apache Commons Collections (v 4.1)
 Eclipse Collections (fka GS Collections, v 9.0)
 Google Guava’s Collections (v23)
 Vavr’s Collections (fka Javaslang, v0.9)
 (links are to their user guide/documentation!)
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Collection Frameworks Timeline
Java 2
1998
• Jakarta
Collections 1.0
• 2001
• Apache
Collections 3.0
(AC)
• 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
• AC 4.0
• Nov. 2013
Java 8
2014
• Javaslang 1.0
• Mar. 2014
• AC 4.1
• Nov. 2015
• Eclipse Collections
7.0 (EC)
• Jan. 2016
• EC 8.0 (Java 8)
• Sept. 2016
• Guava 20.0
• Oct. 2016
• Javaslang 2.1a
• Nov. 2016
Java 9
2017
• Guava 21.0
(Java 8)
• Jan. 2017
• EC 8.1
• Mar. 2017
• Vavr 0.9
• May 2017
• Guava 22.0
• May 2017
• EC 8.2
• Jun 2017
• Guava 23.0
• Aug 2017
• EC 9.0
• Sep 2017
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Latest Versions
Framework Latest Version Released
Apache Collections 4.1 November 2015
Eclipse Collections 9.1 December 2017
Google Guava 24.0 February 2018
Java Streams JDK 9 September 2017
Vavr 0.9.2 November 2017
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Collections.compare();
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Use Case – Deck of Cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
A Deck of Cards – Only the Types
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Shared Code – Cartesian
Productpublic 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)));
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Eclipse Collections – Cartesian Product
public static LazyIterable<Card> lazyCards()
{
return Sets.cartesianProduct(
EnumSet.allOf(Rank.class),
EnumSet.allOf(Suit.class),
Card::new);
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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, 3 forks
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Tests
• ObjectSizeCalculator.getObjectSize()
• Internal class in Nashorn
• Java 8
• Smaller numbers are better
• We test the size of the data structures created in
each code example
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test – ImmutableList
207,258
225,904
187,521 190,509
180,838
0
50,000
100,000
150,000
200,000
250,000
Scoreops/s
Framework
ImmutableList
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test – ImmutableList
2888
2776 2776
2896
2824
2700
2720
2740
2760
2780
2800
2820
2840
2860
2880
2900
2920
Framework
Bytes
ImmutableList
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
public JDK8DeckOfCards() {
this.cards = Collections.unmodifiableList(
Card.streamCards().sorted().collect(Collectors.toList()));
this.cardsBySuit =
this.cards.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(
Card::getSuit,
Collectors.mapping(Function.identity(),
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList))),
Collections::unmodifiableMap));
}
JDK Collections – “ImmutableList”
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cards =
Collections.unmodifiableList(
Card.streamCards()
.sorted()
.collect(Collectors.toList()));
JDK Collections – “ImmutableList”
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public ApacheCommonsDeckOfCards() {
this.cards = ListUtils.unmodifiableList(
Card.streamCards().sorted().collect(Collectors.toList()));
ListValuedMap<Suit, Card> cbs = MultiMapUtils.newListValuedHashMap();
this.cards.forEach(card -> cbs.put(card.getSuit(), card));
this.cardsBySuit = MultiMapUtils.unmodifiableMultiValuedMap(cbs);
}
Apache Collections – “ImmutableList”
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cards =
ListUtils.unmodifiableList(
Card.streamCards()
.sorted()
.collect(Collectors.toList()));
Apache Collections – “ImmutableList”
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public EclipseCollectionsDeckOfCards() {
this.cards = Card.lazyCards().toSortedList().toImmutable();
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
Eclipse Collections – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cards =
Card.lazyCards()
.toSortedList()
.toImmutable();
Eclipse Collections – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public GoogleGuavaDeckOfCards() {
this.cards =
Card.streamCards().sorted().collect(ImmutableList.toImmutableList());
this.cardsBySuit = Multimaps.index(this.cards, Card::getSuit);
}
Google Guava – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cards =
Card.streamCards()
.sorted()
.collect(ImmutableList.toImmutableList());
Google Guava – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
public VavrDeckOfCards() {
this.cards = Card.streamCards().sorted().collect(List.collector());
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
Vavr – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cards =
Card.streamCards()
.sorted()
.collect(List.collector());
Vavr – ImmutableList
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test - groupBy
832,841
617,693
459,074
1,123,706
695,402
-
200,000
400,000
600,000
800,000
1,000,000
1,200,000
Scoreops/s
Framework
groupBy
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test – groupBy
3336
2952
3136
3336
4208
0
500
1000
1500
2000
2500
3000
3500
4000
4500
Framework
Bytes
groupBy
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class JDK8DeckOfCards {
private List<Card> cards;
private Map<Suit, List<Card>> cardsBySuit;
public JDK8DeckOfCards() {
this.cards = Collections.unmodifiableList(
Card.streamCards().sorted().collect(Collectors.toList()));
this.cardsBySuit =
this.cards.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(
Card::getSuit,
Collectors.mapping(Function.identity(),
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList))),
Collections::unmodifiableMap));
}
JDK Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cardsBySuit =
this.cards.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(
Card::getSuit,
Collectors.mapping(Function.identity(),
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList))),
Collections::unmodifiableMap));
JDK Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class ApacheCommonsDeckOfCards {
private List<Card> cards;
private MultiValuedMap<Suit, Card> cardsBySuit;
public ApacheCommonsDeckOfCards() {
this.cards = ListUtils.unmodifiableList(
Card.streamCards().sorted().collect(Collectors.toList()));
ListValuedMap<Suit, Card> cbs = MultiMapUtils.newListValuedHashMap();
this.cards.forEach(card -> cbs.put(card.getSuit(), card));
this.cardsBySuit = MultiMapUtils.unmodifiableMultiValuedMap(cbs);
}
Apache Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
ListValuedMap<Suit, Card> cbs =
MultiMapUtils.newListValuedHashMap();
this.cards.forEach(
card -> cbs.put(card.getSuit(), card));
this.cardsBySuit =
MultiMapUtils.unmodifiableMultiValuedMap(cbs);
Apache Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public class EclipseCollectionsDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public EclipseCollectionsDeckOfCards() {
this.cards = Card.lazyCards().toSortedList().toImmutable();
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
Eclipse Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cardsBySuit =
this.cards.groupBy(Card::getSuit);
Eclipse Collections – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Google Guava – Group By
public class GoogleGuavaDeckOfCards {
private ImmutableList<Card> cards;
private ImmutableListMultimap<Suit, Card> cardsBySuit;
public GoogleGuavaDeckOfCards() {
this.cards =
Card.streamCards().sorted().collect(ImmutableList.toImmutableList());
this.cardsBySuit = Multimaps.index(this.cards, Card::getSuit);
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cardsBySuit =
Multimaps.index(this.cards, Card::getSuit);
Google Guava – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Vavr – Group By
public class VavrDeckOfCards {
private List<Card> cards;
private Map<Suit, ? extends List<Card>> cardsBySuit;
public VavrDeckOfCards() {
this.cards = Card.streamCards().sorted().collect(List.collector());
this.cardsBySuit = this.cards.groupBy(Card::getSuit);
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
this.cardsBySuit =
this.cards.groupBy(Card::getSuit);
Vavr – Group By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test - Deck of Cards
207,258
225,904
187,521 190,509 180,838
ImmutableList
832,841
617,693
459,074
1,123,706
695,402
groupBy
166,268
179,728
147,495
179,159
165,415
Deck of Cards
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test – Deck of Cards
3608
3216
3400
3720
5480
0
1000
2000
3000
4000
5000
6000
Framework
Bytes
Deck of Cards
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test - countsBySuit
1,302,792
1,797,399
1,488,693
1,553,906
1,432,836
0
200,000
400,000
600,000
800,000
1,000,000
1,200,000
1,400,000
1,600,000
1,800,000
2,000,000
Scoreops/s
Framework
countsBySuit
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test - countsBySuit
672
408
704
600 600
0
100
200
300
400
500
600
700
800
Framework
Bytes
countsBySuit
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test - countsByRank
889,401
1,339,267
1,136,795
1,289,520
1,208,456
0
200,000
400,000
600,000
800,000
1,000,000
1,200,000
1,400,000
1,600,000
Scoreops/s
Framework
countsByRank
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test – countsByRank
1816
1136
1848
1600 1600
0
200
400
600
800
1000
1200
1400
1600
1800
2000
Framework
Bytes
countsByRank
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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()));
}
JDK Collections – Count By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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));
}
Apache Collections – Count By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public Bag<Suit> countsBySuit()
{
return this.cards.countBy(Card::getSuit);
}
public Bag<Rank> countsByRank()
{
return this.cards.countBy(Card::getRank);
}
Eclipse Collections – Count By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
public Multiset<Suit> countsBySuit() {
return this.cards.stream()
.collect(Multisets.toMultiset(
Card::getSuit, e -> 1, HashMultiset::create));
}
public Multiset<Rank> countsByRank() {
return this.cards.stream()
.collect(Multisets.toMultiset(
Card::getRank, e -> 1, HashMultiset::create));
}
Google Guava – Count By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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()));
}
Vavr – Count By
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Problem Statement – Deck of
Cards
1. Create Deck of Cards
• Store Cards in an “ImmutableList”
• (Cartesian product of Suit x Rank)
• Group the cards by Suit in an “ImmutableListMultimap”
• (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 “ImmutableList” of five Sets of five
cards
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Performance Test – Deal Hands
935,213
1,320,811
935,860 945,125
716,883
0
200,000
400,000
600,000
800,000
1,000,000
1,200,000
1,400,000
Scoreops/s
Framework
Deal
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Memory Test – Deal Hands
3528
2440
3488 3536
3120
0
500
1000
1500
2000
2500
3000
3500
4000
Framework
Bytes
Deal
Apache EC Guava JDK Vavr
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
JDK Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand)
{
return Collections.unmodifiableList(
IntStream.range(0, hands)
.mapToObj(i -> this.deal(shuffled, cardsPerHand))
.collect(Collectors.toList()));
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Apache Collections – Deal Hands
public List<Set<Card>> dealHands(
Deque<Card> shuffled,
int hands,
int cardsPerHand)
{
return ListUtils.unmodifiableList(
IntStream.range(0, hands)
.mapToObj(i -> this.deal(shuffled, cardsPerHand))
.collect(Collectors.toList()));
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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));
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
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());
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Vavr – Deal Hands
public List<Set<Card>> dealHands(
List<Card> shuffled,
int hands,
int cardsPerHand)
{
List<Set<Card>> list = List.empty();
for (int i = 0; i < hands; i++) {
Tuple2<Set<Card>, List<Card>> tuple2 =
this.deal(shuffled, cardsPerHand);
shuffled = tuple2._2();
list = list.append(tuple2._1());
}
return list;
}
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Feature JDK Apache Guava Eclipse Vavr 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
Collection Framework Comparison
*(E)ager, (L)azy, (S)erial, (P)arallel – Functional API
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Links
 The Collections Compare Project
https://github.com/nikhilnanivadekar/CollectionsCom
pare
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
? & !
Collections.compare(()->{…})
@TheDonRaab @leomrlima @NikhilNanivade#eurojug
Thanks!

More Related Content

PPTX
Collections.compare(JDK, Eclipse, Guava, Apache...);
PPTX
Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017
PDF
Scala. Inception.
PPTX
Scala on Android
KEY
Pier - no kernel left behind
PPT
JavaScript Obfuscation
KEY
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
PPTX
Collections.compare(JDK, Eclipse, Guava, Apache...); DevoxxUS 2017
Collections.compare(JDK, Eclipse, Guava, Apache...);
Collections.compare(JDK, Eclipse, Guava, Apache...); GIDS 2017
Scala. Inception.
Scala on Android
Pier - no kernel left behind
JavaScript Obfuscation
NOSQL101, Or: How I Learned To Stop Worrying And Love The Mongo!
Collections.compare(JDK, Eclipse, Guava, Apache...); DevoxxUS 2017

Similar to Collections.compare(() -> JDK; Apache; Eclipse, Guava...}); (20)

PDF
JavaOne 2017 - Collections.compare:JDK, Eclipse, Guava, Apache... [CON1754]
PDF
JavaCro 2014 Scala and Java EE 7 Development Experiences
PDF
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
PPTX
An Introduction To jQuery
PDF
The cost of learning - advantage of mixer2
PDF
Scaladroids: Developing Android Apps with Scala
PDF
Javantura v2 - All Together Now - making Groovy and Scala sing together - Din...
PDF
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
ODP
This upload requires better support for ODP format
PDF
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
PPT
Mongo-Drupal
PPT
Backbone js-slides
PPT
J query b_dotnet_ug_meet_12_may_2012
PDF
Using Backbone.js with Drupal 7 and 8
PPT
Backbone js
PPTX
Debugging in drupal 8
PDF
DEX: Seminar Tutorial
PDF
Intro to Java 8 Closures (Dainius Mezanskas)
PDF
Intro to Java 8 Lambdas
PDF
DIとトレイとによるAndroid開発の効率化
JavaOne 2017 - Collections.compare:JDK, Eclipse, Guava, Apache... [CON1754]
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
An Introduction To jQuery
The cost of learning - advantage of mixer2
Scaladroids: Developing Android Apps with Scala
Javantura v2 - All Together Now - making Groovy and Scala sing together - Din...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
This upload requires better support for ODP format
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
Mongo-Drupal
Backbone js-slides
J query b_dotnet_ug_meet_12_may_2012
Using Backbone.js with Drupal 7 and 8
Backbone js
Debugging in drupal 8
DEX: Seminar Tutorial
Intro to Java 8 Closures (Dainius Mezanskas)
Intro to Java 8 Lambdas
DIとトレイとによるAndroid開発の効率化
Ad

More from Java Usergroup Berlin-Brandenburg (19)

PDF
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
PDF
Built To Last - Nachhaltige Software-Entwicklung
PDF
Feature Toggles On Steroids
PDF
Resilience mit Hystrix
PDF
Analysis of software systems using jQAssistant and Neo4j
PDF
Get Back in Control of your SQL
PDF
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
PDF
Selbstvorstellung Steria Mummert Consulting
PDF
Graphdatenbanken mit Neo4j
PDF
Jbosseapclustering 130605100557-phpapp02
PDF
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
PDF
How long can you afford to Stop The World?
PDF
JavaOne Update zur Java Plattform
PDF
Java EE 7 - Overview and Status
PDF
Fighting Layout Bugs
PDF
Die Java Plattform Strategie
PDF
PDF
Continuous Delivery in der Praxis
Microbenchmarks - Wer nicht weiß, was er misst misst Mist
Built To Last - Nachhaltige Software-Entwicklung
Feature Toggles On Steroids
Resilience mit Hystrix
Analysis of software systems using jQAssistant and Neo4j
Get Back in Control of your SQL
Die fabelhafte Welt Java(Script)-getriebener Enterprise-WebApps (mit Ext JS)
Selbstvorstellung Steria Mummert Consulting
Graphdatenbanken mit Neo4j
Jbosseapclustering 130605100557-phpapp02
Jbossas7alsplattformmodernerenterprise anwendungen-130604114410-phpapp02
How long can you afford to Stop The World?
JavaOne Update zur Java Plattform
Java EE 7 - Overview and Status
Fighting Layout Bugs
Die Java Plattform Strategie
Continuous Delivery in der Praxis
Ad

Recently uploaded (20)

PDF
Nekopoi APK 2025 free lastest update
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
top salesforce developer skills in 2025.pdf
PPTX
history of c programming in notes for students .pptx
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PPT
Introduction Database Management System for Course Database
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
assetexplorer- product-overview - presentation
PPTX
Introduction to Artificial Intelligence
Nekopoi APK 2025 free lastest update
Odoo Companies in India – Driving Business Transformation.pdf
Reimagine Home Health with the Power of Agentic AI​
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
2025 Textile ERP Trends: SAP, Odoo & Oracle
Upgrade and Innovation Strategies for SAP ERP Customers
Operating system designcfffgfgggggggvggggggggg
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Understanding Forklifts - TECH EHS Solution
Navsoft: AI-Powered Business Solutions & Custom Software Development
Designing Intelligence for the Shop Floor.pdf
top salesforce developer skills in 2025.pdf
history of c programming in notes for students .pptx
PTS Company Brochure 2025 (1).pdf.......
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Introduction Database Management System for Course Database
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
assetexplorer- product-overview - presentation
Introduction to Artificial Intelligence

Collections.compare(() -> JDK; Apache; Eclipse, Guava...});

Editor's Notes

  • #3: We'd like to have a session for both beginner and seasoned developers that would help them choose which collections framework is better for their projects. While they can look very much alike, there are key differences regarding performance, style of programming and memory impact that are not explicit until you already committed to using one framework over the other.   Our goal is to present common use cases for collections, the frameworks available and how we use them. There should be little slides for use case descriptions and comparison, and actual tests will run from our IDEs. 
  • #4: We'd like to have a session for both beginner and seasoned developers that would help them choose which collections framework is better for their projects. While they can look very much alike, there are key differences regarding performance, style of programming and memory impact that are not explicit until you already committed to using one framework over the other.   Our goal is to present common use cases for collections, the frameworks available and how we use them. There should be little slides for use case descriptions and comparison, and actual tests will run from our IDEs.