Unlock Java Efficiency: Master Guava’s Most Powerful Features
This article introduces the essential Guava utilities for Java developers, covering data validation, immutable collections, collection factories, multiset and multimap handling, advanced string operations, and simple caching, all with clear code examples to make your code more elegant and robust.
Guava is Google’s open‑source core library for Java, offering utilities such as data validation, immutable collections, collection factories, multiset, multimap, string handling, and caching.
Recently I noticed a colleague’s code heavily using Guava, which made the code much cleaner, so I share the most useful Guava features.
Data Validation
Guava provides concise methods for null checks and argument validation.
Non‑null check
<code><!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.0-jre</version>
</dependency></code> <code>String param = "未读代码";
String name = Preconditions.checkNotNull(param);
System.out.println(name); // 未读代码
String param2 = null;
String name2 = Preconditions.checkNotNull(param2); // NullPointerException
System.out.println(name2);
</code>You can also provide a custom error message:
<code>String param2 = null;
String name2 = Preconditions.checkNotNull(param2, "param2 is null");
// java.lang.NullPointerException: param2 is null
</code>Argument validation works similarly:
<code>String param = "www.github.com2";
String wdbyte = "www.github.com";
Preconditions.checkArgument(wdbyte.equals(param), "[%s] 404 NOT FOUND", param);
// java.lang.IllegalArgumentException: [www.github.com2] 404 NOT FOUND
</code>Guava can also check collection indexes:
<code>List<String> list = Lists.newArrayList("a", "b", "c", "d");
int index = Preconditions.checkElementIndex(5, list.size());
// java.lang.IndexOutOfBoundsException: index (5) must be less than size (4)
</code>Immutable Collections
Immutable collections cannot be modified after creation, offering thread safety, memory efficiency, and safe sharing.
Thread‑safe because elements cannot change.
Safe to expose to third‑party code.
Potentially lower memory usage.
Useful as constant collections.
Creation methods
<code>ImmutableSet<String> immutableSet = ImmutableSet.of("a", "b", "c");
immutableSet.forEach(System.out::println);
// a
// b
// c
ImmutableSet<String> immutableSet2 = ImmutableSet.<String>builder()
.add("hello")
.add(new String("未读代码"))
.build();
immutableSet2.forEach(System.out::println);
// hello
// 未读代码
ArrayList<String> arrayList = new ArrayList();
arrayList.add("www.github.com");
arrayList.add("https");
ImmutableSet<String> immutableSet3 = ImmutableSet.copyOf(arrayList);
immutableSet3.forEach(System.out::println);
// www.github.com
// https
</code>Attempting to modify an immutable collection throws
UnsupportedOperationException.
<code>ArrayList<String> arrayList = new ArrayList();
arrayList.add("www.github.com");
arrayList.add("https");
List<String> list = Collections.unmodifiableList(arrayList);
list.forEach(System.out::println); // www.github.com https
list.add("未读代码"); // java.lang.UnsupportedOperationException
</code>Collection Factory Methods
Guava provides convenient factory methods for creating and populating collections.
Creating collections
<code>List<String> list1 = Lists.newArrayList();
List<String> list2 = Lists.newArrayList("a", "b", "c");
List<String> list3 = Lists.newArrayListWithCapacity(10);
LinkedList<String> linkedList1 = Lists.newLinkedList();
CopyOnWriteArrayList<String> cowArrayList = Lists.newCopyOnWriteArrayList();
HashMap<Object, Object> hashMap = Maps.newHashMap();
ConcurrentMap<Object, Object> concurrentMap = Maps.newConcurrentMap();
TreeMap<Comparable, Object> treeMap = Maps.newTreeMap();
HashSet<Object> hashSet = Sets.newHashSet();
HashSet<String> newHashSet = Sets.newHashSet("a", "a", "b", "c");
</code>Set operations
<code>Set<String> newHashSet1 = Sets.newHashSet("a", "a", "b", "c");
Set<String> newHashSet2 = Sets.newHashSet("b", "b", "c", "d");
SetView<String> intersectionSet = Sets.intersection(newHashSet1, newHashSet2);
System.out.println(intersectionSet); // [b, c]
SetView<String> unionSet = Sets.union(newHashSet1, newHashSet2);
System.out.println(unionSet); // [a, b, c, d]
SetView<String> setView = Sets.difference(newHashSet1, newHashSet2);
System.out.println(setView); // [a]
</code>Multiset and Multimap
Guava’s
HashMultisetcounts element occurrences efficiently.
<code>ArrayList<String> arrayList = Lists.newArrayList("a", "b", "c", "d", "a", "c");
HashMultiset<String> multiset = HashMultiset.create(arrayList);
multiset.elementSet().forEach(s -> System.out.println(s + ":" + multiset.count(s)));
/*
a:2
b:1
c:2
d:1
*/
</code>For one‑to‑many mappings,
HashMultimapsimplifies code:
<code>HashMultimap<String, String> multimap = HashMultimap.create();
multimap.put("狗", "大黄");
multimap.put("狗", "旺财");
multimap.put("猫", "加菲");
multimap.put("猫", "汤姆");
System.out.println(multimap.get("猫")); // [加菲, 汤姆]
</code>String Operations
Joining strings
<code>ArrayList<String> list = Lists.newArrayList("a", "b", "c", null);
String join = Joiner.on(",").skipNulls().join(list);
System.out.println(join); // a,b,c
String join1 = Joiner.on(",").useForNull("空值").join("旺财", "汤姆", "杰瑞", null);
System.out.println(join1); // 旺财,汤姆,杰瑞,空值
</code>Splitting strings
<code>String str = ",a , ,b ,";
Iterable<String> split = Splitter.on(",")
.omitEmptyStrings()
.trimResults()
.split(str);
split.forEach(System.out::println);
// a
// b
</code>Cache
Guava provides a lightweight cache with size limits and expiration.
<code>CacheLoader<String, Animal> cacheLoader = new CacheLoader<String, Animal>() {
@Override
public Animal load(String s) {
return null;
}
};
LoadingCache<String, Animal> loadingCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(3, TimeUnit.SECONDS)
.removalListener(new MyRemovalListener())
.build(cacheLoader);
loadingCache.put("狗", new Animal("旺财", 1));
loadingCache.put("猫", new Animal("汤姆", 3));
loadingCache.put("狼", new Animal("灰太狼", 4));
loadingCache.invalidate("猫");
Animal animal = loadingCache.get("狼");
System.out.println(animal);
Thread.sleep(4 * 1000);
System.out.println(loadingCache.get("狼")); // triggers expiration
class MyRemovalListener implements RemovalListener<String, Animal> {
@Override
public void onRemoval(RemovalNotification<String, Animal> notification) {
String reason = String.format("key=%s,value=%s,reason=%s",
notification.getKey(), notification.getValue(), notification.getCause());
System.out.println(reason);
}
}
class Animal {
private String name;
private Integer age;
@Override
public String toString() {
return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}';
}
public Animal(String name, Integer age) {
this.name = name;
this.age = age;
}
}
</code>Conclusion
Guava offers a rich set of utilities that simplify common Java development tasks, improve code readability, and enhance performance. Integrating Guava into any Java project can make your code more elegant and maintainable.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
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.