Skip to content
illyfrancis edited this page Jul 19, 2013 · 14 revisions

Old presentation

Immutable collections

  • use immutable collections, instead of unmodifirable
    • ImmuatableList, Set, SortedSet, Map, (SortedMap - oneday)
    • immutable vs unmodifiable
      • immutability guarantee, easier to use, faster, less memory

Examples

  • constant set using JDK (11:55)
  • a little better Collections.unmodifiableSet( new LinkedHashSet<Integer>( Arrays.asList(...)));
    • ImmutableSet LUCKY_NUMBERS = ImmutableSet.of(4,8,15...);
      • of() <- java.util.EnumSet pattern (** check it out**)
      • constant map - ImmutableMap<String, Integer> ENG_TO_INT = ImmutableMap.with("four", 4)...build() (15:16)
      • Defensive copies
        • ImmutableSet.copyOf(numbers) (17:10)
      • factories
        • ImmutableSet.of() (== Collections.emptyset ?)
        • ImmutableSet.of(a) (== Collections.singleton?)
        • ImmutableSet.of(a, b, c)
        • ImmutableSet.copyOf(someIterator);
        • ImmutableSet.copyOf(someIterable);
      • static final ImmutableMap<Integer, String> MAP = ImmutableMap.of(1, "one", 2, "two");
      • there should be a builders pattern (check current imp)
    • Don't take nulls!!!

Multisets

  • Type of collection
Collection behaviour
  • Can it have duplicates?
  • Is ordering significant? (for equals())
  • Iteration order
    • insertion-ordered? (Linked list) comparator-ordered? (Tree) user-ordered? (Array)
    • something else well-defined?
    • or it just doesn't matter?

In general, the first two determine the interface type, and the third tends to influce your choice of implementation

List vs. Set
  • Set: unordered equality, no dups
  • List: ordered equauality, can have dups
Diagram (31:50)
                 Ordered?
             Y             N
Dups? +--------------+----------+
  Y   |     List     | Multiset |
      +--------------+----------+
  N   | (UniqueList) |    Set   |
      +--------------+----------+
Multiset: unordered equality, can have dups
  • == Bag
  • use cases,
    • hand of cards, compare same hands
    • are these Lists equal, ignoring order?
    • histograms, what distinct tags am I using on my blog, and how many times do I use each one?
Example code, before (36:07)
Map<String, Integer> tags
  = new HashMap<String, Integer>();
for (BlogPost post : getAllBlogPosts()) {
  for (String tag: post.getTags()) {
    int value = tags.containsKey(tag) ? tags.get(tag) : 0;
    tags.put(tag, value + 1);
  }
}
  • distinct tags: tags.keySet()
  • count for "java" tag: tags.containsKey("java") ? tags.get("java") : 0;
  • total count: // oh crap...
  • Java tutorial shows proper way of doing this!!! (have a look)
Example code, after(38:27)
Multiset<String> tags = HashMultiset.create();
for (BlogPost post : getAllBlogPosts()) {
  tags.addAll(post.getTags())
}
  • distinct tags: tags.elementSet();
  • count for "java" tag: tags.count("java")
  • total count: tags.size()
Example, after after (40:10)
  • if need to remove/decrement? (Multiset supports it)
  • concurrency? (instead of locking the entire map, use ConcurrentMultiset)
Multiset API (00:41)
  • Everything from collection plus
  • count, add, remove, setCount, etc
Multiset implementations
  • ImmutableMultiset
  • HashMultiset
  • LinkedHashMultiset
  • TreeMultiset
  • EnumMultset
  • ConcurrentMultiset

Multimaps

Before
Map<Salesperson, List<Sale>> map = new HashMap<Salesperson, List<Sale>>();

public void makeSale(Salesperson salesPerson, Sale sale) {
  List<Sale> sales = map.get(salesPerson);
  if (sales == null) {
    sales = new ArrayList<Sale>();
    map.put(salesPerson, sales);
  }
  sales.add(sale);
}
with multimaps
Multimap<Salesperson, Sale> multimap = ArrayListMultimap.create();

public void void makeSale(Salesperson salesPerson, Sale sale) {
  multimap.put(salesPerson, sale);
}
  • collection of key-value pairs (entries) like a Map except that keys don't have to be unique {a=1, a=2, b=3}
  • or as Map use asMap() {a=[1,2], b=[3]}
  • get() view implements subtype, (13:44)
  • re-look 14:20, good example biggiest sale
  • view collections - Multimap has six: get(), keys(), keySet(), values(), entries(), asMap()
Multimap vs Map
  • Most Map methods are identical on Multimap
    • size(), isEmpty()
    • containsKey(), containsValue()
    • put(), putAll()
    • clear()
    • values()
  • The others have analogues
    • get() returns Collection instead of V
    • remove(K) becomes remove(K, V) and removeAll(K)
    • keySet() becomes keys()(well, and and KeySet())
    • entrySet() becomes entries()
  • And Multimap has a few new things
    • containsEntry(), replaceValues()

BiMap

  • aka, unique-values map, guarantees its values are unique as well as its keys
  • has inverse() view
    • ` bimap.inverse().inverse() == bimap
  • stop creating two separate forward and backward Maps!

ReferenceMap (21:39)

  • when dealing with weak or soft refereces
  • a generalization of java.util.WeakHashMap
  • Nine possible combos:
    • strong, weak, or soft keys
    • strong, weak or soft values
  • fully concurrent
    • implements ConcurrentMap
    • cleanup done on GC Thread
  • and more...
  • used a lot for caching,
    • when using strong reference, the object doesn't get gced? but weak reference does????? (24:00)

Ordering class

  • Comparator is easy to implement but a pain to use
  • Ordering is Comparator++ (or RichComparator)

Ordering<String> caseless = Ordering.forComparator(String.CASE_INSENSITIVE_ORDER)

  • Also there's method like min(iterable), max(iter), isIncreasing(iterable), sortedCopy(iterable), reverse()...

Static factory methods

Rather than we type
Multimap<String, Class<? extends Handler>> handlers =
  new ArrayListMultimap<String, Class<? extends Handler>>();
do this
Multimap<String, Class<? extends Handler>> handlers =
  ArrayListMultimap.create();
  • also provided for JDK collections, like Lists, Sets, Maps
  • with overloads to accept Iterables to copy elements from

Working with Iterator and Iterables

  • Collection is a good abstraction when all your data is in memory
  • Sometimes you want to process large amounts of data in a single pass
  • Implementing Collection is possible but cumbersome, and won't behave nicely
  • Iterator and Iterable are often all you need
  • GoogleCollection methods accept Iterator and Iterable whenever practical

Iterators and Iterables classes

  • These classes have parallel APIs, one for Iterator and the other for Iterable
Iterable transform(Iterable, Function)
Iterable filter(Iterable, Predicate)
T find(Iterable<T>, Predicate)
Iterable concat(Iterable<Iterable>)
Iterable cycle(Iterable)
T getOnlyElement(Iterable<T>)
Iterable<T> reverse(List<T>)
...
  • These methods are LAZY!
    • backing iterators aren't accessed until needed

Clone this wiki locally