Deep Dive into Guava: A Powerful Toolkit for Java Developers
This article provides a comprehensive guide to Google Guava, covering its core modules such as collections, concurrency, string utilities, I/O, caching, event bus, functional programming, reflection, and best‑practice code examples that demonstrate how to simplify and strengthen Java development.
What is Guava?
Guava is an open‑source Java utility library that extends the standard Java library with collections, concurrency, string handling, I/O, mathematics, caching, and functional programming utilities.
Download and Install Guava
Add Guava as a dependency via Maven or Gradle.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency> implementation 'com.google.guava:guava:30.1-jre'Hello Guava Example
Use Strings.isNullOrEmpty to check a string.
import com.google.common.base.Strings;
public class HelloGuava {
public static void main(String[] args) {
String input = "Hello, Guava!";
boolean isNullOrEmpty = Strings.isNullOrEmpty(input);
System.out.println(isNullOrEmpty ? "Input string is null or empty." : "Input string is not null or empty.");
}
}Basic Utilities
String Utilities
Stringsprovides common string operations.
isNullOrEmpty(String) – checks for null or empty strings.
nullToEmpty(String) – converts null to an empty string.
emptyToNull(String) – converts an empty string to null.
import com.google.common.base.Strings;
public class StringUtilExample {
public static void main(String[] args) {
String str = "Hello, Guava!";
System.out.println(Strings.isNullOrEmpty(str));
System.out.println(Strings.nullToEmpty(null));
System.out.println(Strings.emptyToNull(""));
}
}Collection Operations
Create immutable collections, filter, and transform collections.
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.List;
public class CollectionExamples {
public static void main(String[] args) {
// Immutable list
ImmutableList<String> immutable = ImmutableList.of("Apple", "Banana", "Orange");
System.out.println(immutable);
// Filter
List<String> fruits = Lists.newArrayList("Apple", "Banana", "Orange", "Cherry");
Iterable<String> filtered = Iterables.filter(fruits, f -> f.startsWith("A"));
System.out.println(Lists.newArrayList(filtered));
// Transform
List<String> upper = Lists.transform(fruits, String::toUpperCase);
System.out.println(upper);
}
}Preconditions
The Preconditions class validates arguments, state, and boolean conditions.
import com.google.common.base.Preconditions;
public class PreconditionsDemo {
public static void main(String[] args) {
String input = "Hello";
Preconditions.checkNotNull(input, "Input cannot be null");
int age = 25;
Preconditions.checkArgument(age >= 0, "Age must be non‑negative");
new PreconditionsDemo().initialize();
}
private boolean initialized = false;
public void initialize() {
Preconditions.checkState(!initialized, "Object already initialized");
initialized = true;
}
}Collection Handling
Guava extends the Java Collections Framework with immutable collections and helper classes.
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
public class ImmutableAndHelpers {
public static void main(String[] args) {
ImmutableList<String> list = ImmutableList.of("Apple", "Banana", "Orange");
System.out.println(list);
List<String> mutable = Lists.newArrayList("Apple", "Banana", "Orange");
System.out.println(Lists.reverse(mutable));
}
}Traversal, Filtering, Transformation
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.List;
public class CollectionOps {
public static void main(String[] args) {
List<String> fruits = Lists.newArrayList("Apple", "Banana", "Orange", "Cherry");
// Iterate
for (String f : fruits) System.out.println(f);
// Filter
Iterable<String> filtered = Iterables.filter(fruits, f -> f.startsWith("A"));
System.out.println(Lists.newArrayList(filtered));
// Transform
List<String> upper = Lists.transform(fruits, String::toUpperCase);
System.out.println(upper);
}
}Functional Programming Support
Function
import com.google.common.base.Function;
import com.google.common.base.Functions;
public class FunctionDemo {
public static void main(String[] args) {
Function<String, String> fn = Functions.compose(
s -> "Prefix: " + s,
String::toUpperCase);
System.out.println(fn.apply("guava"));
}
}Predicate
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
public class PredicateDemo {
public static void main(String[] args) {
Predicate<String> pred = Predicates.and(
s -> s.length() > 3,
s -> s.startsWith("A"));
System.out.println(pred.test("Apple"));
}
}Supplier
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
public class SupplierDemo {
public static void main(String[] args) {
Supplier<String> lazy = Suppliers.memoize(() -> {
System.out.println("Computing value");
return "Lazy Value";
});
System.out.println(lazy.get()); // computes
System.out.println(lazy.get()); // cached
}
}Concurrency Utilities
ListenableFuture
import com.google.common.util.concurrent.*;
import java.util.concurrent.Executors;
public class ListenableFutureDemo {
public static void main(String[] args) {
ListeningExecutorService exec = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
ListenableFuture<String> future = exec.submit(() -> {
Thread.sleep(2000);
return "Hello, ListenableFuture!";
});
Futures.addCallback(future, new FutureCallback<String>() {
public void onSuccess(String result) { System.out.println("Success: " + result); exec.shutdown(); }
public void onFailure(Throwable t) { System.out.println("Failure: " + t.getMessage()); exec.shutdown(); }
}, exec);
}
}Cache
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class CacheDemo {
public static void main(String[] args) {
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
cache.put("key1", "value1");
cache.put("key2", "value2");
System.out.println(cache.getIfPresent("key1")); // value1
System.out.println(cache.getIfPresent("key3")); // null
}
}Event Bus
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
class MessageEvent {
private final String message;
MessageEvent(String m) { this.message = m; }
String getMessage() { return message; }
}
class MessageSubscriber {
@Subscribe
void onMessage(MessageEvent e) { System.out.println("Received: " + e.getMessage()); }
}
public class EventBusDemo {
public static void main(String[] args) {
EventBus bus = new EventBus();
bus.register(new MessageSubscriber());
bus.post(new MessageEvent("Hello, EventBus!"));
}
}Real‑World Scenario
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
class OrderEvent { private final String orderId; OrderEvent(String id) { this.orderId = id; } String getOrderId() { return orderId; } }
class OrderProcessor {
@Subscribe
void processOrder(OrderEvent e) { System.out.println("Processing order: " + e.getOrderId()); }
}
public class OrderEventDemo {
public static void main(String[] args) {
EventBus bus = new EventBus();
bus.register(new OrderProcessor());
bus.post(new OrderEvent("123456"));
}
}I/O Utilities
CharSource
import com.google.common.io.CharSource;
import com.google.common.io.Files;
import com.google.common.base.Charsets;
import java.io.File;
import java.io.IOException;
public class CharSourceDemo {
public static void main(String[] args) throws IOException {
File file = new File("example.txt");
CharSource source = Files.asCharSource(file, Charsets.UTF_8);
System.out.println(source.read());
source.lines().forEach(l -> System.out.println("Line: " + l));
}
}CharSink
import com.google.common.io.CharSink;
import com.google.common.io.Files;
import com.google.common.base.Charsets;
import java.io.File;
import java.io.IOException;
public class CharSinkDemo {
public static void main(String[] args) throws IOException {
File file = new File("output.txt");
CharSink sink = Files.asCharSink(file, Charsets.UTF_8);
sink.write("Hello, Guava!");
sink.append(" Append");
try (CharSink other = Files.asCharSink(new File("other.txt"), Charsets.UTF_8)) {
other.write("Another file");
}
}
}String Utilities
CaseFormat
import com.google.common.base.CaseFormat;
public class CaseFormatDemo {
public static void main(String[] args) {
String camel = "helloWorld";
String underscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, camel);
System.out.println(underscore); // hello_world
String backToCamel = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, underscore);
System.out.println(backToCamel); // helloWorld
}
}Joiner
import com.google.common.base.Joiner;
import java.util.Arrays;
import java.util.List;
public class JoinerDemo {
public static void main(String[] args) {
List<String> words = Arrays.asList("Hello", "Guava", "Joiner");
System.out.println(Joiner.on(" ").join(words));
List<String> withNull = Arrays.asList("Hello", null, "Guava", null, "Joiner");
System.out.println(Joiner.on(" ").skipNulls().join(withNull));
System.out.println(Joiner.on(" ").useForNull("NULL").join(withNull));
}
}Reflection Utilities
TypeToken
import com.google.common.reflect.TypeToken;
import java.util.List;
import java.util.Map;
public class TypeTokenDemo {
public static void main(String[] args) {
TypeToken<List<String>> listToken = new TypeToken<List<String>>() {};
TypeToken<Map<String, Integer>> mapToken = new TypeToken<Map<String, Integer>>() {};
System.out.println("List raw: " + listToken.getRawType());
System.out.println("Map raw: " + mapToken.getRawType());
System.out.println("List arg: " + listToken.resolveType(List.class.getTypeParameters()[0]));
System.out.println("Map key arg: " + mapToken.resolveType(Map.class.getTypeParameters()[0]));
System.out.println("List match: " + listToken.isAssignableFrom(listToken.resolveType(List.class.getTypeParameters()[0])));
System.out.println("Map key match: " + mapToken.isAssignableFrom(mapToken.resolveType(Map.class.getTypeParameters()[0])));
}
}Reflection
import com.google.common.reflect.Reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionDemo {
public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
Field f = Reflection.field(MyClass.class, "myField");
System.out.println("Field: " + f);
Method m = Reflection.method(MyClass.class, "myMethod");
System.out.println("Method: " + m);
MyClass proxy = Reflection.newProxy(MyClass.class, (p, method, args) -> {
System.out.println("Proxy invoked");
return null;
});
proxy.myMethod();
}
private static class MyClass {
private String myField;
public void myMethod() { System.out.println("Original method"); }
}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Shepherd Advanced Notes
Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
