Gen AI in Business - Global Trends Report 2024.pdf
Google guava
1. Google Guava
Thomas Ferris Nicolaisen
@tfnico
www.tfnico.com
Code at http://github.com/tfnico/guava-examples
2. 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
3. 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) {
...
5. 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"));
}
7. 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
}
8. 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, '
}
9. //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");
10. import com.google.common.base.*;
@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);
}
11. 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!
}
12. 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());
}
13. 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
}
14. 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());
}
15. 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());
}
16. import com.google.common.base.*;
private Function<Ingredients, Cake> bake() {
return new Function<Ingredients, Cake>() {
public Cake apply(Ingredients ingredients) {
return new Cake(ingredients);
}
};
}
17. 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);
}
18. 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();
}
20. 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!
}
21. import com.google.common.io.*;
@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);
}
}
22. 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);
}
23. 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);
}
24. import com.google.common.net.InetAddresses;
@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);
}
}
25. TODO
(For this presentation)
• 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
26. When to think Guava?
• For loops
• Temporary collections
• Mutable collections
• if( x == null)
• In short: method complexity