【Java】Java 开发利器:Guava 工具类全方位使用总结

日常 Java 开发过程中,原生 JDK 提供的工具类多多少少存在短板:空指针泛滥、集合创建繁琐、字符串拼接拆分代码冗余、本地缓存需要自己手动实现等问题层出不穷。Google 开源的Guava工具库就是为了解决这类痛点而生,封装了大量实用 API,覆盖参数校验、空值处理、增强集合、字符串操作、本地缓存等高频开发场景。今天结合日常项目实战,梳理 Guava 常用功能与落地代码。

一、Maven 快速引入依赖

使用 Guava 第一步在pom.xml引入坐标,选用稳定版:

<!-- Guava依赖 -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

二、基础工具类:规避 NPE 与参数校验

1. Optional 空值处理

原生代码直接使用null极易引发空指针异常,Guava 的Optional强制开发者主动处理空值,杜绝隐性 NPE。

import com.google.common.base.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        // 1. 创建非空对象
        Optional<String> opt1 = Optional.of("Java-Guava");
        // 2. 允许传入null
        Optional<String> opt2 = Optional.fromNullable(null);

        // 判断是否有值
        System.out.println(opt1.isPresent()); // true
        // 空值时设置默认返回
        String res = opt2.or("默认字符串");
        System.out.println(res); // 默认字符串
    }
}

2. Preconditions 参数前置校验

项目入参校验是刚需,原生 if 判断代码臃肿,Preconditions一行代码完成参数合法性校验,不满足直接抛出异常。

import com.google.common.base.Preconditions;

public class PreconditionsDemo {
    public static void getUserInfo(Integer userId){
        // 校验参数不能为null
        Preconditions.checkNotNull(userId,"用户ID不能为空");
        // 校验数值范围
        Preconditions.checkArgument(userId>0,"用户ID必须大于0");
        System.out.println("合法用户ID:"+userId);
    }

    public static void main(String[] args) {
        getUserInfo(10);
        // getUserInfo(-1); // 抛出IllegalArgumentException
    }
}

3. 便捷 Object 工具方法

JDK7 的java.util.Objects设计大量参考 Guava,在低版本 JDK 环境中可直接使用 Guava 自带的对象比较、哈希方法。

三、Guava 增强集合(开发高频使用)

Guava 拓展了 JDK 没有的特殊集合:不可变集合、Multiset、Multimap、BiMap,同时提供 Lists/Sets 便捷创建集合。

1. 不可变集合 Immutable

原生Collections.unmodifiableList只是视图包装,原集合修改后视图同步变化;Guava 不可变集合是真正副本,原集合改动不影响自身,天生线程安全,可作为常量使用

import com.google.common.collect.ImmutableList;

public class ImmutableDemo {
    public static void main(String[] args) {
        // 快速创建不可变集合
        ImmutableList<String> list = ImmutableList.of("MySQL","Java","Linux");
        // list.add("C++"); // 调用add直接抛异常,不允许修改
    }
}

2. Lists 工具:简化集合操作

import com.google.common.collect.Lists;
import java.util.List;

public class ListsDemo {
    public static void main(String[] args) {
        // 1.快速初始化集合
        List<Integer> list = Lists.newArrayList(1,2,3,4,5);
        // 2.集合分页,每2个元素分为一组
        List<List<Integer>> pageList = Lists.partition(list,2);
        System.out.println(pageList); // [[1,2],[3,4],[5]]
        // 3.集合反转
        List<Integer> reverse = Lists.reverse(list);
        System.out.println(reverse); // [5,4,3,2,1]
    }
}

3. Multiset:可重复元素集合,快速统计频次

普通 Set 不允许重复元素,统计元素出现次数需要 Map 手动计数,Multiset 原生支持重复存储 + 计数。

import com.google.common.collect.Multiset;
import com.google.common.collect.HashMultiset;

public class MultisetDemo {
    public static void main(String[] args) {
        Multiset<String> multiSet = HashMultiset.create();
        multiSet.add("Java");
        multiSet.add("Java");
        multiSet.add("MySQL");
        // 获取指定元素出现次数
        System.out.println(multiSet.count("Java")); // 2
    }
}

4. Multimap:一键实现一个 key 对应多个 value

原生 Map<K,List<V>> 代码繁琐,Multimap 天然支持一键多值映射。

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class MultimapDemo {
    public static void main(String[] args) {
        Multimap<String,String> map = ArrayListMultimap.create();
        map.put("后端","Java");
        map.put("后端","Go");
        map.put("前端","Vue");
        System.out.println(map.get("后端")); // [Java, Go]
    }
}

5. BiMap 双向映射:键值互相查询

普通 Map 只能 key 查 value,BiMap 可通过inverse()反转映射,用 value 反向查 key。

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

public class BiMapDemo {
    public static void main(String[] args) {
        BiMap<Integer,String> biMap = HashBiMap.create();
        biMap.put(1,"admin");
        // value反向获取key
        BiMap<String,Integer> inverseMap = biMap.inverse();
        System.out.println(inverseMap.get("admin")); //1
    }
}

四、字符串处理:Joiner 与 Splitter 告别冗余代码

1. Joiner:字符串拼接

原生循环拼接、处理 null 空值代码繁杂,Joiner 链式配置,轻松处理空元素。

import com.google.common.base.Joiner;

public class JoinerDemo {
    public static void main(String[] args) {
        String[] arr = {"Java",null,"MySQL","Linux"};
        // 忽略null元素拼接
        String s1 = Joiner.on(",").skipNulls().join(arr);
        System.out.println(s1); // Java,MySQL,Linux

        // null替换为指定字符
        String s2 = Joiner.on(",").useForNull("空").join(arr);
        System.out.println(s2); // Java,空,MySQL,Linux
    }
}

2. Splitter:灵活字符串拆分

原生 String.split 存在正则坑点,Splitter 拆分规则可控。

import com.google.common.base.Splitter;
import java.util.List;

public class SplitterDemo {
    public static void main(String[] args) {
        String str = "Java,,MySQL, Linux ";
        // 按逗号拆分+忽略空串+去除首尾空格
        List<String> list = Splitter.on(",")
                .omitEmptyStrings()
                .trimResults()
                .splitToList(str);
        System.out.println(list); // [Java, MySQL, Linux]
    }
}

五、Guava 本地缓存 Cache

开发中高频查询、查询耗时高的数据,可使用 Guava Cache 实现轻量级本地缓存,无需引入 Redis 等中间件。

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) throws Exception {
        // 构建缓存:最大容量100,写入后5分钟过期
        Cache<String,Integer> cache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(5, TimeUnit.MINUTES)
                .build();

        // 存入缓存
        cache.put("user:1001",1001);
        // 获取缓存
        Integer userId = cache.getIfPresent("user:1001");
        System.out.println(userId);
    }
}

六、总结

Guava 几乎覆盖后端日常开发的各类小工具场景,合理引入项目可以大量精简重复代码、减少空指针、优化集合与字符串处理逻辑。后续我会持续更新 Guava 高级用法,包含事件总线、范围工具、异步工具等内容,感兴趣可以持续关注博客更新。

Tags:

发表回复

Your email address will not be published. Required fields are marked *.

*
*