找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1072

积分

0

好友

153

主题
发表于 4 天前 | 查看: 10| 回复: 0

Google Guava是Java开发中广受赞誉的核心工具库,它封装了诸如数据校验、不可变集合、增强集合操作、缓存、字符串处理等常用功能,能显著提升代码的简洁性与健壮性。

引入Guava只需添加Maven依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.0-jre</version>
</dependency>

一、更优雅的数据校验

日常开发中的校验逻辑无非是非空判断预期值判断。虽然使用 if...else 能够实现,但代码往往显得冗长。Guava的Preconditions类提供了更清晰的语义化校验方式。

1. 非空判断

Preconditions.checkNotNull 不仅能进行非空校验,还能自定义异常信息,便于快速定位问题。

String param = “未读代码”;
String name = Preconditions.checkNotNull(param);
System.out.println(name); // 输出:未读代码

String param2 = null;
String name2 = Preconditions.checkNotNull(param2, “param2 is null”);
// 抛出异常:java.lang.NullPointerException: param2 is null

2. 预期值判断

checkArgument方法可用于检查业务参数是否符合预期。

String param = “www.wdbyte.com2”;
String expected = “www.wdbyte.com”;
Preconditions.checkArgument(expected.equals(param), “[%s] 404 NOT FOUND”, param);
// 抛出异常:java.lang.IllegalArgumentException: [www.wdbyte.com2] 404 NOT FOUND

3. 索引越界检查

在操作集合或数组时,可以使用checkElementIndex来避免越界异常。

// Guava 快速创建List
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)指创建后无法被修改(增、删、改)的集合。它具有线程安全、节省内存、适合作为常量等优点。

创建不可变集合的三种方式

// 1. 使用of方法直接创建
ImmutableSet<String> immutableSet = ImmutableSet.of(“a”, “b”, “c”);

// 2. 使用构造器(Builder)
ImmutableSet<String> immutableSet2 = ImmutableSet.<String>builder()
    .add(“hello”)
    .add(“未读代码”)
    .build();

// 3. 从现有集合拷贝创建
ArrayList<String> arrayList = new ArrayList();
arrayList.add(“www.wdbyte.com”);
ImmutableSet<String> immutableSet3 = ImmutableSet.copyOf(arrayList);

对不可变集合进行修改操作会抛出UnsupportedOperationException

Guava与JDK不可变集合的区别

  1. 拒绝null值:Guava创建的不可变集合不接受null元素,这符合绝大多数业务场景。
  2. 真正的独立性:通过Guava ImmutableList.copyOf()创建的集合与原集合完全独立,后续对原集合的修改不会影响不可变集合。而JDK的Collections.unmodifiableList()仅包装原集合,原集合变化会导致“不可变”视图一同变化。
  3. 引用可变性:如果集合元素是对象,那么对象内部的属性仍然可以修改。

三、增强的集合操作

Guava提供了极为便捷的集合工厂方法和集合运算工具。

1. 工厂方法创建集合

使用ListsSetsMaps等工具类可以一行代码创建并初始化集合,极大地提升了编码效率,是编写Java代码时的常用技巧。

// 创建并初始化ArrayList
List<String> list = Lists.newArrayList(“a”, “b”, “c”);
// 创建指定初始容量的ArrayList
List<String> listWithCapacity = Lists.newArrayListWithCapacity(10);
// 创建HashSet并初始化,自动去重
Set<String> set = Sets.newHashSet(“a”, “a”, “b”, “c”); // 结果为 [a, b, c]
// 快速创建HashMap
Map<String, String> map = Maps.newHashMap();

2. 集合运算(交集、并集、差集)

Set<String> set1 = Sets.newHashSet(“a”, “b”, “c”);
Set<String> set2 = Sets.newHashSet(“b”, “c”, “d”);

// 交集
SetView<String> intersection = Sets.intersection(set1, set2);
System.out.println(intersection); // 输出 [b, c]

// 并集
SetView<String> union = Sets.union(set1, set2);
System.out.println(union); // 输出 [a, b, c, d]

// 差集 (set1中有,set2中没有)
SetView<String> difference = Sets.difference(set1, set2);
System.out.println(difference); // 输出 [a]

四、强大的多值集合

Guava引入了如MultisetMultimap等新集合类型,解决了许多常见但用JDK集合实现起来很繁琐的场景。

1. Multiset:可计数的Set

Multiset像一个Set,但可以存储多个相等的元素并统计其数量。它非常适合用来统计词频。

List<String> words = Lists.newArrayList(“a”, “b”, “c”, “d”, “a”, “c”);
HashMultiset<String> multiset = HashMultiset.create(words);
multiset.elementSet().forEach(s ->
    System.out.println(s + “:” + multiset.count(s))
);
// 输出:
// a:2
// b:1
// c:2
// d:1

2. Multimap:一键对多值的Map

Multimap实现了类似 Map<K, List<V>>Map<K, Set<V>> 的结构,但使用起来远比嵌套集合简单直观。

// 传统Map<String, List<String>>实现分类很繁琐
// 使用Multimap
HashMultimap<String, String> animalMultimap = HashMultimap.create();
animalMultimap.put(“狗”, “大黄”);
animalMultimap.put(“狗”, “旺财”);
animalMultimap.put(“猫”, “加菲”);
animalMultimap.put(“猫”, “汤姆”);

System.out.println(animalMultimap.get(“猫”)); // 输出 [加菲, 汤姆]

五、灵活的字符串处理

1. 连接字符串(Joiner)

Joiner提供了比JDK String.join()更强大的功能,如跳过null值或为null指定默认值。

List<String> list = Lists.newArrayList(“a”, “b”, “c”, null);
// 跳过null
String result1 = Joiner.on(“,”).skipNulls().join(list);
System.out.println(result1); // 输出 a,b,c

// 为null指定替换值
String result2 = Joiner.on(“,”).useForNull(“空值”).join(“旺财”, null, “汤姆”);
System.out.println(result2); // 输出 旺财,空值,汤姆

2. 分割字符串(Splitter)

JDK的String.split()方法在处理末尾空串时行为不一致。Splitter则提供了完全可控且行为一致的分割逻辑,理解其使用方式也是处理字符串数据结构的基础。

String str = “,a ,,b ,”;
Iterable<String> parts = Splitter.on(“,”)
    .omitEmptyStrings() // 忽略空字符串
    .trimResults()      // 移除每个结果两端的空白字符
    .split(str);
parts.forEach(System.out::println);
// 输出:
// a
// b

六、轻量级内存缓存

对于不需要引入Redis等分布式缓存的小规模缓存场景,Guava Cache是一个完美的选择。它可以设置容量限制、过期策略,并支持缓存移除监听。

// 1. 定义缓存加载器(当缓存未命中时调用)
CacheLoader<String, String> cacheLoader = new CacheLoader<String, String>() {
    @Override
    public String load(String key) {
        // 此处可实现从数据库或其他地方加载数据的逻辑
        return “从数据库加载的” + key;
    }
};

// 2. 构建缓存
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
    .maximumSize(1000)                     // 最大容量
    .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
    .removalListener(notification -> {     // 移除监听器
        System.out.println(String.format(“Key %s 被移除了,原因:%s”,
            notification.getKey(), notification.getCause()));
    })
    .build(cacheLoader);

// 3. 使用缓存
cache.put(“name”, “Guava”);
String value = cache.get(“name”); // 若存在则返回,不存在则调用load方法加载
System.out.println(value); // 输出: Guava

Guava Cache作为一个本地缓存解决方案,其功能与数据库/中间件中的缓存组件互补,常用于提升局部访问性能。

总结

Guava库极大地丰富了Java标准库的功能,通过提供数据校验、不可变集合、增强集合、字符串工具和轻量缓存等实用组件,能够帮助开发者写出更简洁、健壮和高效的代码。将其引入项目,可以有效减少样板代码,提升开发体验与代码质量。




上一篇:Spring Boot项目中用Lambda优化Service调用:封装统一管理组件实践
下一篇:揭秘Surge AI:如何以百人团队打造LLM训练核心数据供应链
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 20:52 , Processed in 0.147739 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表