Google guava

tfnico 9,919 views 27 slides Jun 16, 2010
Slide 1
Slide 1 of 27
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27

About This Presentation

Some quick examples of Google Guava, mostly in the base package.


Slide Content

Google Guava
Thomas Ferris Nicolaisen
@tfnico
www.tfnico.com
Code at http://github.com/tfnico/guava-examples

So much goodness in here...
•com.google.common.annotation
•com.google.common.base
•com.google.common.collect
•com.google.common.io
•com.google.common.net
•com.google.common.primitives
•com.google.common.util.concurrent

import com.google.common.annotations.*; /**
* An annotation that indicates that the visibility of a type or member has
* been relaxed to make the code testable.
*
*/
public @interface VisibleForTesting
/**
* Use this method for determining that a cart item is eligible for retail
pickup.
*
* @param item with productClass PRINT, or exportName "INDEXPRINT"
* @return true if it is allowed, false if not
*/
@VisibleForTesting
static boolean allowedForRetailPickup( final CartItem item) {
...

@Test
public void charSetsAndDefaults()
{
// Here's some charsets
Charset utf8 = Charsets. UTF_8;
assertTrue(utf8.canEncode());
// Primitive defaults:
Integer defaultValue = Defaults.defaultValue( int.class);
assertEquals(0, defaultValue.intValue());
}import com.google.common.base.*;

@Test
public void equalityAndIdentity()
{
//These could be useful for building equals methods
assertFalse(Equivalences.equals().equivalent( "you", null));
assertTrue(Equivalences.identity().equivalent( "hey", "hey"));
}import com.google.common.base.*;

@Test
public void joinSomeStrings()
{
ImmutableSet<String> strings = ImmutableSet.of( "A", "B", "C");
String joined = Joiner.on( ":").join(strings);
assertEquals( "A:B:C", joined);
}import com.google.common.base.*;

@Test
public void splitSomeStrings()
{
String string = "A:B:C";
String[] parts = string.split( ":"); //the old way
String backTogether = Joiner.on( ":").join(parts);
assertEquals(string, backTogether);
String gorbleString = ": A::: B : C :::";
Iterable<String> gorbleParts = Splitter.on( ":")
.omitEmptyStrings().trimResults().split(gorbleString);
String gorbleBackTogether = Joiner.on( ":").join(gorbleParts);
assertEquals(string, gorbleBackTogether); // A:B:C
}import com.google.common.base.*;

@Test
public void moreFunWithStrings()
{
assertNull(Strings.emptyToNull( ""));
assertEquals( "", Strings.nullToEmpty( null));
// About the only thing we ever used in commons-lang? :)
assertTrue(Strings.isNullOrEmpty( ""));
assertEquals( "oioioi", Strings.repeat("oi", 3));
assertEquals( "Too short ", Strings.padEnd("Too short", 15, ' '));
}import com.google.common.base.*;

//Some customers
Customer bob = new Customer(1, "Bob");
Customer lisa = new Customer(2, "Lisa");
Customer stephen = new Customer(3, "Stephen");
Customer ken = new Customer(null,"Ken");

@Test
public void toStringsAndHashcodes()
{
Object[] bobAndLisa = new Object[] { bob, lisa };
// Make some hashcode!
int hashCode = Objects.hashCode( bob, lisa);
assertEquals(Arrays.hashCode(bobAndLisa), hashCode);
// Build toString method
String string = Objects.toStringHelper( bob)
.add("name", bob.getName())
.add( "id", bob.getId()).toString();
assertEquals( "Customer{name=Bob, id=1}" , string);
}import com.google.common.base.*;

@Test(expected = NullPointerException. class)
public void needAnIntegerWhichIsNeverNull()
{
Integer defaultId = null;
Integer kensId = ken.getId() != null ? ken.getId() : defaultId;
// this one does not throw!
int kensId2 = Objects.firstNonNull( ken.getId(), defaultId);
assertEquals(0, kensId2);
// But the above does!
}import com.google.common.base.*;

@Test(expected = IllegalArgumentException. class)
public void somePreconditions()
{
// Pretend this is a constructor:
Preconditions.checkNotNull( lisa.getId()); // Will throw NPE
Preconditions.checkState(! lisa.isSick()); // Will throw ILE
Preconditions.checkArgument( lisa.getAddress() != null,
"No description for customer with id %s" ,lisa.getId());
}import com.google.common.base.*;

@Test
public void fancierFunctions()
{
Function<Customer, Boolean> isCustomerWithOddId
= new Function<Customer, Boolean>()
{
public Boolean apply(Customer customer)
{
return customer.getId().intValue() % 2 != 0;
}
};
assertTrue(isCustomerWithOddId.apply( bob));
assertFalse(isCustomerWithOddId.apply( lisa));
// Functions are great for higher-order functions, like
// project/transform, and fold
}import com.google.common.base.*;

@Test
public void somePredicates()
{
ImmutableSet<Customer> customers =
ImmutableSet.of(bob, lisa, stephen);
Predicate<Customer> itsBob = Predicates.equalTo( bob);
Predicate<Customer> itsLisa = Predicates.equalTo( lisa);
Predicate<Customer> bobOrLisa = Predicates.or(itsBob, itsLisa);
// Predicates are great to pass in to higher-order functions
// like filter/search
Iterable<Customer> filtered = Iterables.filter(customers, bobOrLisa);
assertEquals(2, ImmutableSet.copyOf(filtered).size());
}import com.google.common.base.*;

@Test
public void someSuppliers()
{
//Imagine we have Supploer that produces ingredients
IngredientsFactory ingredientsFactory = new IngredientsFactory();

//A function 'bake' - (see next slide)
bake();

//Then it's pretty easy to get a Factory that bakes cakes :)
Supplier<Cake> cakeFactory =
Suppliers.compose(bake(), ingredientsFactory);
cakeFactory.get();
cakeFactory.get();
cakeFactory.get();

assertEquals(3, ingredientsFactory.getNumberOfIngredientsUsed());
}import com.google.common.base.*;

private Function<Ingredients, Cake> bake() {
return new Function<Ingredients, Cake>() {
public Cake apply(Ingredients ingredients) {
return new Cake(ingredients);
}
};
}import com.google.common.base.*;

@Test
public void someThrowables()
{
try
{
try{
Integer.parseInt( "abc");
}
catch(RuntimeException e){
if(e instanceof ClassCastException) throw e; //old-style
Throwables.propagateIfInstanceOf(e, NumberFormatException. class); //the same
Throwables.propagateIfPossible(e); // Propagates if it is Error or RuntimeException
try {
Throwables.throwCause(e, true);
} catch (Exception e1) {
Throwables.propagate(e1); //Wraps if its a checked exception,
//or lets it flow if not
}
}
}
catch(RuntimeException e){
Throwables.getCausalChain(e);
Throwables.getRootCause(e);
Throwables.getStackTraceAsString(e);
}
import com.google.common.base.*;

@Test
public void someEnums()
{
assertEquals( "UNDER_DOG",
CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE,
"underDog"));

//Controlling services
Service service = new FunkyService();
service.start();
assertEquals(Service.State. RUNNING, service.state());
service.stop();
}import com.google.common.base.*;

@Test
public void someSets()
{
ImmutableSet<Customer> customers1 =
ImmutableSet.of(bob, lisa, stephen);
ImmutableSet<Customer> customers2 =
ImmutableSet.of(stephen, ken);

assertEquals(4, Sets.union(customers1, customers2).size());

assertEquals(ImmutableSet.of( stephen),
Sets.intersection(customers1, customers2));
}import com.google.common.collect.*;

@Test(expected=NullPointerException. class)
public void someConstraints()
{
//instead of new HashSet<Customer>()
HashSet<Customer> customers = Sets.newHashSet();
customers.add( null); //this works. But should it?

Set<Customer> noMoreNulls =
Constraints.constrainedSet(customers, Constraints.notNull());
noMoreNulls.add( null); //boom!
}import com.google.common.collect.*;

@Test
public void messAroundWithFile()
{
File file = new File("woop.txt");
try {
Files.touch(file);

Files.write( "Hey sailor!", file, Charsets.UTF_8);

//Breakpoint here.. have a look at the file..

Files.toByteArray(file);
Files.newInputStreamSupplier(file);
assertEquals( "Hey sailor!", Files.readFirstLine(file, Charsets. UTF_8));
assertEquals( "Hey sailor!", Files.toString(file, Charsets. UTF_8));

Files.deleteRecursively(file);

} catch (IOException e) {
Throwables.propagate(e);
}
}import com.google.common.io.*;

@Test
public void closingAndFlushing()
{
InputStream inputStream = System. in;
try {
inputStream.close(); //The old way
} catch (IOException e) {
Throwables.propagate(e);
}
Closeables.closeQuietly(inputStream ); //The new way

//Or flush:
PrintStream outputStream = System. out;
Flushables.flushQuietly(outputStream);
}import com.google.common.io.*;

@Test
public void classPathResources()
{
//This:
Resources.getResource( "com/tfnico/examples/guava/BaseTest.class" );

//instead of this:
String location = "com/tfnico/examples/guava/BaseTest.class" ;
URL resource2 =
this.getClass().getClassLoader().getResource(location);
Preconditions.checkArgument(resource2!= null,
"resource %s not found" , location);
}import com.google.common.io.*;

@Test
public void iNetAddressIsFixed()
{
try {

/**
* Unlike InetAddress.getByName(),
* the methods of this class never cause DNS services to be accessed.
* For this reason, you should prefer these methods as much as possible
* over their JDK equivalents whenever you are expecting to handle only
* IP address string literals -- there is no blocking DNS penalty for
* a malformed string.
*/
InetAddresses.forString( "0.0.0.0");

//Instead of this...
InetAddress.getByName( "0.0.0.0");

} catch (UnknownHostException e) {
Throwables.propagate(e);
}
}import com.google.common.net.InetAddresses;

TODO

Show off primitives

Show off CharMatcher

Add more collection examples

Add more higher order functions

Do concurrency stuff

Do cooler io stuff

Find patterns of old code that can be replaced
(For this presentation)

When to think Guava?
•For loops
•Temporary collections
•Mutable collections
•if( x == null)
•In short: method complexity

Arright, let’s try!