Java常用开发工具

Maven 依赖

java 复制代码
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>33.0.0-jre</version>
</dependency>

第一部分:JDK 无法替代的"独门绝技"

这部分功能是引入 Guava 的主要理由,JDK 原生集合库暂时无法优雅实现。

  1. Multimap (多值映射)
    场景:一个 Key 对应多个 Value(如 Map<String, List>)。
    痛点:JDK 原生写法需要繁琐的判空、创建 List、添加元素。
java 复制代码
// ✅ Guava 写法
// ArrayListMultimap: Value 是 List (允许重复)
// HashMultimap: Value 是 Set (自动去重)
Multimap<String, String> multimap = ArrayListMultimap.create();

// 1. 自动处理容器初始化
multimap.put("Backend", "Java");
multimap.put("Backend", "Go");
multimap.put("Frontend", "Vue");

// 2. 获取集合 (返回 List 或 Set)
Collection<String> list = multimap.get("Backend"); 
// 输出: [Java, Go]

// 3. 转换为标准 Map
Map<String, Collection<String>> standardMap = multimap.asMap();
  1. BiMap (双向映射)
    场景:Key 和 Value 一一对应,需要通过 Value 反查 Key。
    痛点:JDK 需要维护两个 Map,容易导致数据不一致。
java 复制代码
// ✅ Guava 写法
BiMap<String, Integer> userIdMap = HashBiMap.create();

// 1. 强制 Value 唯一性 (如果 Value 重复会抛异常)
userIdMap.put("Alice", 1001);
userIdMap.put("Bob", 1002);

// 2. 正向查
Integer id = userIdMap.get("Alice"); // 1001

// 3. 反向查 (核心功能)
String name = userIdMap.inverse().get(1002); // "Bob"

// 4. 强制覆盖 (如果 Value 已存在,踢掉旧的 Key)
userIdMap.forcePut("Charlie", 1001); // Alice 被移除
  1. Table (二维表)
    场景:需要两个 Key 确定一个 Value(如 Map<Row, Map<Col, Val>>)。
    痛点:JDK 写法嵌套层级深,判空逻辑极其复杂。
java 复制代码
// ✅ Guava 写法
Table<String, String, Integer> table = HashBasedTable.create();

// 1. 写入 (行, 列, 值)
table.put("ClassA", "Math", 90);
table.put("ClassA", "English", 85);
table.put("ClassB", "Math", 60);

// 2. 读取
Integer score = table.get("ClassA", "Math");

// 3. 行切片 (获取 ClassA 的所有成绩)
Map<String, Integer> rowMap = table.row("ClassA"); 
// {Math=90, English=85}

// 4. 列切片 (获取所有班级的 Math 成绩)
Map<String, Integer> colMap = table.column("Math"); 
// {ClassA=90, ClassB=60}
  1. Guava Cache (本地缓存,很少使用)
    场景:单机轻量级缓存,需要自动过期、LRU 淘汰。
    注意:高性能场景建议使用 Caffeine(API 与 Guava 几乎一致,性能更强)。
java 复制代码
// ✅ Guava 写法
LoadingCache<String, User> userCache = CacheBuilder.newBuilder()
    .maximumSize(1000)                 // 容量限制 (LRU)
    .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后过期
    .recordStats()                     // 开启统计
    .build(new CacheLoader<String, User>() {
        @Override
        public User load(String key) {
            return db.getUser(key);    // 缓存击穿时的加载逻辑
        }
    });

// 使用
User user = userCache.get("u1001");
  1. RateLimiter (单机限流)
    场景:接口防刷、第三方 API 调用频率限制。
java 复制代码
// ✅ Guava 写法
// 每秒生成 5 个令牌 (QPS = 5)
RateLimiter limiter = RateLimiter.create(5.0);

// 阻塞获取
limiter.acquire(); 
doBusiness();

// 非阻塞获取 (尝试抢一下,抢不到就算了)
if (limiter.tryAcquire()) {
    doBusiness();
} else {
    return "系统繁忙";
}

第二部分:工具类增强 (比 JDK 更好用)

  1. String 处理 (Splitter)
    痛点:JDK 的 String.split 会保留尾部空串,且无法自动去除空格。
java 复制代码
String str = " a, ,b, c,,";

// ❌ JDK 写法
String[] split = str.split(","); 
// 结果包含空格和空串,处理麻烦

// ✅ Guava 写法
List<String> list = Splitter.on(",")
    .trimResults()       // 去除两端空格
    .omitEmptyStrings()  // 去除空串
    .splitToList(str);
// 结果: ["a", "b", "c"]
  1. 集合切分 (Partition)
    场景:批量插入数据库,将大 List 切分为小 List。
java 复制代码
List<Integer> ids = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

// ✅ Guava 写法
// 将 List 切分为大小为 3 的子列表
List<List<Integer>> parts = Lists.partition(ids, 3);
// 结果: [[1, 2, 3], [4, 5, 6], [7]]
  1. 集合运算 (Sets)
    场景:计算交集、并集、差集。
java 复制代码
Set<Integer> s1 = Sets.newHashSet(1, 2, 3);
Set<Integer> s2 = Sets.newHashSet(3, 4, 5);

// ✅ Guava 写法
Sets.difference(s1, s2);   // 差集: [1, 2]
Sets.intersection(s1, s2); // 交集: [3]
Sets.union(s1, s2);        // 并集: [1, 2, 3, 4, 5]

第三部分:已被 JDK 8+ 替代的特性 (迁移指南)

原则:以下功能 Guava 虽然提供,但 JDK 8+ 原生实现已经足够好,新代码请直接使用 JDK。

  1. 字符串连接 (Joiner)
    Guava: Joiner.on(",").join(list)
    JDK 8+ (推荐):
java 复制代码
// 场景 1: 简单的 String join
String result = String.join(",", "a", "b", "c");

// 场景 2: List 转 String
String result = list.stream().collect(Collectors.joining(","));

注:如果需要 skipNulls 功能,Guava 的 Joiner 依然有优势,JDK 需要 filter(Objects::nonNull)。

  1. 空值处理 (Optional)

Guava: com.google.common.base.Optional (已过时)

JDK 8+ (推荐):

java 复制代码
Optional<User> opt = Optional.ofNullable(user);
User u = opt.orElse(new User());
  1. 列表转换 (Lists.transform)
    Guava: Lists.transform(list, func) (懒加载,有坑)
    JDK 8+ (推荐):
java 复制代码
List<String> names = users.stream()
    .map(User::getName)
    .collect(Collectors.toList());
  1. 基础集合创建
    Guava: Lists.newArrayList(), Maps.newHashMap()
    JDK 7+ (推荐):
java 复制代码
// 菱形语法,无需 Guava 工具类
List<String> list = new ArrayList<>();
  1. 不可变集合 (Immutable Collections)
    Guava: ImmutableList.of("A", "B")
    JDK 9+ (推荐):
java 复制代码
// 语法更简洁,且 JVM 层面优化更好
List<String> list = List.of("A", "B");
Set<String> set = Set.of("A", "B");
Map<String, Integer> map = Map.of("k1", 1, "k2", 2);

区别:JDK 的 List.of 对 null 检查更严格,且不提供 Builder 模式。如果需要 Builder 模式构建复杂不可变集合,依然推荐 Guava。

  1. 时间处理

Guava: 不涉及

JDK 8+ (推荐): 彻底放弃 Date 和 Calendar,全面拥抱 java.time 包 (LocalDateTime, ZonedDateTime, Duration)。

相关推荐
彩妙不是菜喵2 小时前
c++:初阶/初始模版
开发语言·c++
Allen_LVyingbo2 小时前
具备安全护栏与版本化证据溯源的python可审计急诊分诊平台复现
开发语言·python·安全·搜索引擎·知识图谱·健康医疗
专注于大数据技术栈2 小时前
java学习--LinkedList
java·开发语言·学习
weixin199701080162 小时前
安家 GO item_get - 获取安家详情数据接口对接全攻略:从入门到精通
java·大数据·python·golang
予枫的编程笔记2 小时前
【Java进阶】Spring Security详解
java·spring security·security
D_FW2 小时前
【Java】SpringAMQP+RabbitMQ消息可靠性保证
java·rabbitmq·java-rabbitmq
区区一散修2 小时前
0.IntelliJ IDEA的安装和使用
java·ide·intellij-idea
Wzx1980122 小时前
自研开发的前后端项目部署流程
vue.js·python
这周也會开心2 小时前
多线程与并发-知识总结1
java·多线程·并发
野犬寒鸦2 小时前
从零起步学习RabbitMQ || 第二章:RabbitMQ 深入理解概念 Producer、Consumer、Exchange、Queue 与企业实战案例
java·服务器·数据库·分布式·后端·rabbitmq