Created
February 23, 2010 01:49
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.atomicobject.misc; | |
import com.google.common.base.Function; | |
import com.google.common.base.Joiner; | |
import com.google.common.base.Predicate; | |
import com.google.common.base.Predicates; | |
import com.google.common.collect.Collections2; | |
import com.google.common.collect.ForwardingMap; | |
import com.google.common.collect.ImmutableList; | |
import com.google.common.collect.ImmutableMap; | |
import com.google.common.collect.ImmutableSet; | |
import com.google.common.collect.Iterables; | |
import com.google.common.collect.LinkedHashMultimap; | |
import com.google.common.collect.Lists; | |
import com.google.common.collect.Multimap; | |
import com.google.common.collect.Ordering; | |
import org.junit.Test; | |
import java.util.Collection; | |
import java.util.List; | |
import java.util.Map; | |
import static junit.framework.Assert.assertEquals; | |
/** | |
* Google Collections Library | |
* | |
* A better way to write Java code. The library guides you towards using | |
* a number of functional concepts and techniques like immutable | |
* collections and first class functions. The convenience methods for | |
* creating collections are EXTREMELY useful in unit tests. | |
*/ | |
@SuppressWarnings({"UnusedDeclaration"}) | |
public class DemoGoogleCollectionsTest { | |
/** | |
* Easy to make new collections | |
*/ | |
public void makeNewCollectionsInline() { | |
{ | |
// Don't need to specify generic types on right hand side | |
List<String> names = Lists.newArrayList(); | |
names.add("Joe"); | |
} | |
{ | |
// Empty immutable list | |
List<String> names = ImmutableList.of(); | |
} | |
{ | |
// Immutable list built in one line of code | |
List<String> names = ImmutableList.of("Joe", "Tom"); | |
} | |
{ | |
// Convenient map creation | |
Map<Integer, String> people = ImmutableMap.of(1, "Joe", | |
2, "Tom"); | |
} | |
} | |
/** | |
* Builders for more complicated collections. Good for building static | |
* final collections. | |
*/ | |
@Test | |
public void buildersForNewCollections() { | |
{ | |
List<String> otherNames = ImmutableList.of("Tom", "Jerry"); | |
List<String> names = new ImmutableList.Builder<String>() | |
.add("Joe") | |
.addAll(otherNames) | |
.build(); | |
assertEquals(ImmutableList.of("Joe", "Tom", "Jerry"), names); | |
} | |
{ | |
new ImmutableMap.Builder<String, String>() | |
.put("Joe", "100 Michigan St.") | |
.put("Frank", "1010 Fulton St.") | |
.build(); | |
} | |
{ | |
// Sometimes need to iterate over something to build up a map. | |
List<String> names = ImmutableList.of("Joe", "Henry"); | |
ImmutableMap.Builder<String, Integer> mapBuilder = | |
new ImmutableMap.Builder<String, Integer>(); | |
for (String name : names) { | |
mapBuilder.put(name, name.length()); | |
} | |
// Return an immutable map that was built during the iteration | |
Map<String, Integer> result = mapBuilder.build(); | |
assertEquals(ImmutableMap.of("Joe", 3, "Henry", 5), result); | |
} | |
} | |
/** | |
* Transforming a collection. Transformation is lazy - only happens when | |
* an item in the list is accessed. The transformation will take place | |
* every time | |
* an item is accessed from the new list though. | |
*/ | |
@Test | |
public void transformation() { | |
// Transform list | |
{ | |
List<String> names = ImmutableList.of("Joe", "Frank"); | |
List<Integer> nameLengths = | |
Lists.transform(names, new Function<String, Integer>() { | |
public Integer apply(String name) { | |
return name.length(); | |
} | |
}); | |
assertEquals(ImmutableList.of(3, 5), nameLengths); | |
} | |
// Transform Collection | |
{ | |
Collection<Integer> numbers = ImmutableSet.of(1, 2, 3, 4); | |
Collection<String> strings = | |
Collections2.transform(numbers, new Function<Integer, String>() { | |
public String apply(Integer number) { | |
return String.valueOf(number); | |
} | |
}); | |
// NOTE: due to laziness, sometimes need to force the transformation in | |
// in assertions by using copyOf. | |
assertEquals(ImmutableList.of("1", "2", "3", "4"), | |
ImmutableList.copyOf(strings)); | |
} | |
} | |
/** | |
* Filter collections using a predicate | |
*/ | |
@Test | |
public void filtering() { | |
{ | |
List<String> names = ImmutableList.of("Joe", "Frank", "Henry"); | |
Iterable<String> threeLetterNames = | |
Iterables.filter(names, new Predicate<String>() { | |
public boolean apply(String name) { | |
return name.length() == 3; | |
} | |
}); | |
// Want to compare the result to a list so make | |
// Immutablelist copy for assertEquals to use | |
assertEquals(ImmutableList.of("Joe"), | |
ImmutableList.copyOf(threeLetterNames)); | |
} | |
} | |
/** | |
* Join strings together | |
*/ | |
@Test | |
public void joinStrings() { | |
{ | |
List<String> names = ImmutableList.of("Joe", "Frank", "Henry"); | |
String combined = Joiner.on(", ").skipNulls().join(names); | |
assertEquals("Joe, Frank, Henry", combined); | |
} | |
} | |
/** | |
* Sorting collections | |
*/ | |
@Test | |
public void sortTheStrings() { | |
List<String> names = ImmutableList.of("Joe", "Frank", "Henry"); | |
// Sort by natural sorting order of object | |
{ | |
List<String> sortedNames = Ordering.natural().sortedCopy(names); | |
assertEquals(ImmutableList.of("Frank", "Henry", "Joe"), sortedNames); | |
} | |
// Custom sort order | |
{ | |
Ordering<String> secondLetterOrdering = new Ordering<String>() { | |
public int compare(String s1, String s2) { | |
return s1.substring(1).compareTo(s2.substring(1)); | |
} | |
}; | |
List<String> sortedNames = secondLetterOrdering.sortedCopy(names); | |
assertEquals(ImmutableList.of("Henry", "Joe", "Frank"), sortedNames); | |
} | |
} | |
/** | |
* Multimaps can hold multiple values for the same key. | |
*/ | |
@Test | |
public void multimaps() { | |
Multimap<String, String> cars = LinkedHashMultimap.create(); | |
cars.put("Toyota", "Corolla"); | |
cars.put("Toyota", "Prius"); | |
cars.put("Jeep", "Grand Cherokee"); | |
assertEquals(ImmutableSet.of("Corolla", "Prius"), cars.get("Toyota")); | |
assertEquals(ImmutableSet.of("Grand Cherokee"), cars.get("Jeep")); | |
} | |
/** | |
* Forwarding base classes. Very useful when you want a collection | |
* class with special functionality. You just need to implement | |
* a delegate function, and then override only the other methods | |
* you need. | |
*/ | |
private static class EmptyMap<K,V> extends ForwardingMap<K,V> { | |
@Override | |
protected Map<K,V> delegate() { | |
return ImmutableMap.of(); | |
} | |
} | |
/** | |
* Miscellaneous stuff | |
*/ | |
@Test | |
public void miscellaneous() { | |
// Setup | |
Predicate<String> predicate = Predicates.alwaysTrue(); | |
List<String> names = ImmutableList.of("Joe", "Henry", "Frank"); | |
// Sometimes Java isn't smart enough, so have to specify type | |
formatString(ImmutableList.<String>of()); | |
// Returns true if all items match the predicate | |
Iterables.all(names, predicate); | |
// Returns true if any items match the predicate | |
Iterables.any(names, predicate); | |
// Combine multiple Iterables | |
Iterables.concat(names, names, names); | |
// True if contains item | |
Iterables.contains(names, "Joe"); | |
// Partition an iterable into specified size chunks | |
Iterable<List<String>> chunks = Iterables.partition(names, 2); | |
Iterables.reverse(names); | |
Iterables.toString(names); | |
} | |
private void formatString(List<String> strings) { } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment