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.

macrozheng
macrozheng
macrozheng
Unlock Java Efficiency: Master Guava’s Most Powerful Features

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

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.0-jre</version>
</dependency>
String param = "未读代码";
String name = Preconditions.checkNotNull(param);
System.out.println(name); // 未读代码
String param2 = null;
String name2 = Preconditions.checkNotNull(param2); // NullPointerException
System.out.println(name2);

You can also provide a custom error message:

String param2 = null;
String name2 = Preconditions.checkNotNull(param2, "param2 is null");
// java.lang.NullPointerException: param2 is null

Argument validation works similarly:

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

Guava can also check collection indexes:

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)

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

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

Attempting to modify an immutable collection throws UnsupportedOperationException.

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

Collection Factory Methods

Guava provides convenient factory methods for creating and populating collections.

Creating collections

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");

Set operations

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]

Multiset and Multimap

Guava’s HashMultiset counts element occurrences efficiently.

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
*/

For one‑to‑many mappings, HashMultimap simplifies code:

HashMultimap<String, String> multimap = HashMultimap.create();
multimap.put("狗", "大黄");
multimap.put("狗", "旺财");
multimap.put("猫", "加菲");
multimap.put("猫", "汤姆");
System.out.println(multimap.get("猫")); // [加菲, 汤姆]

String Operations

Joining strings

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); // 旺财,汤姆,杰瑞,空值

Splitting strings

String str = ",a , ,b ,";
Iterable<String> split = Splitter.on(",")
    .omitEmptyStrings()
    .trimResults()
    .split(str);
split.forEach(System.out::println);
// a
// b

Cache

Guava provides a lightweight cache with size limits and expiration.

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;
    }
}

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GuavaimmutabilityString ManipulationMultimap
macrozheng
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.