1. Guava 介绍

1.介绍

Google Guava 是 Google 公司开源的 Java 核心工具库,被称为 "Java 工具库的瑞士军刀"。它包含了大量 Google 内部项目使用的核心库,是提升 Java 开发效率的利器。

1.1 Guava 包含的核心模块

2. Google Guava 版本选择

xml 复制代码
<!-- Guava 核心库 -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.1.3-jre</version>
</dependency>

3. guava 核心工具集

3.1 Joiner - 字符串连接器
java 复制代码
import com.google.common.base.Joiner;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

public class JoinerDemo {

    public static void main(String[] args) {
        // 1. 基本字符串数组连接
        Joiner joiner = Joiner.on(", ");
        String result = joiner.join(Arrays.asList("A", "B", "C"));
        System.out.println("基本连接: " + result);
        // 输出: A, B, C

        // 2. 跳过 null 值
        Joiner skipNullJoiner = Joiner.on(", ").skipNulls();
        String result2 = skipNullJoiner.join(Arrays.asList("A", null, "B", "C"));
        System.out.println("跳过Null: " + result2);
        // 输出: A, B, C

        // 3. null 值替换为指定字符串
        Joiner useNullJoiner = Joiner.on(", ").useForNull("NULL");
        String result3 = useNullJoiner.join(Arrays.asList("A", null, "B", "C"));
        System.out.println("Null替换: " + result3);
        // 输出: A, NULL, B, C

        // 4. Map 连接
        Map<String, String> map = new LinkedHashMap<>();
        map.put("name", "张三");
        map.put("age", "18");
        String mapResult = Joiner.on(", ").withKeyValueSeparator("=").join(map);
        System.out.println("Map连接: " + mapResult);
        // 输出: name=张三, age=18
    }
}
3.2 Splitter - 字符串分割器
java 复制代码
import com.google.common.base.Splitter;
import com.google.common.base.CharMatcher;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

public class SplitterDemo {

    public static void main(String[] args) {
        // 1. 基本分割
        Iterable<String> result1 = Splitter.on(',').split("a,b,c,d");
        System.out.println("基本分割: " + result1);
        // 输出: [a, b, c, d]

        // 2. 去除空白
        Iterable<String> result2 = Splitter.on(',').trimResults().split(" a , b , c ");
        System.out.println("去除空白: " + result2);
        // 输出: [a, b, c]

        // 3. 过滤空白
        Iterable<String> result3 = Splitter.on(',').omitEmptyStrings().split("a,,b,,c");
        System.out.println("过滤空白: " + result3);
        // 输出: [a, b, c]

        // 4. 固定数量分割
        Iterable<String> result4 = Splitter.on(',').limit(3).split("a,b,c,d,e");
        System.out.println("限制数量: " + result4);
        // 输出: [a, b,   c,d,e]

        // 5. Map 解析
        String mapStr = "name=张三&age=18&city=北京";
        Map<String, String> map = Splitter.on('&')
                .withKeyValueSeparator('=')
                .split(mapStr);
        System.out.println("Map解析: " + map);
        // 输出: {name=张三, age=18, city=北京}
    }
}
3.3 Strings 工具类
java 复制代码
import com.google.common.base.Strings;

public class StringsDemo {

    public static void main(String[] args) {
        // 1. 判断字符串是否为空
        System.out.println("isNullOrEmpty(null): " + Strings.isNullOrEmpty(null));
        System.out.println("isNullOrEmpty(''): " + Strings.isNullOrEmpty(""));
        System.out.println("isNullOrEmpty('a'): " + Strings.isNullOrEmpty("a"));
        // 输出: true, true, false

        // 2. 字符串填充
        System.out.println("padStart: '" + Strings.padStart("5", 3, '0') + "'");
        System.out.println("padEnd: '" + Strings.padEnd("abc", 6, '*') + "'");
        // 输出: '005', 'abc***'

        // 3. 字符串重复
        System.out.println("repeat: " + Strings.repeat("ab", 3));
        // 输出: ababab

        // 4. 获取公共前缀/后缀
        System.out.println("commonPrefix: " + Strings.commonPrefix("Hello", "Hell"));
        System.out.println("commonSuffix: " + Strings.commonSuffix("Hell", "Tell"));
        // 输出: Hell, ell
    }
}
3.4 Preconditions 前置条件检查

用于在方法开头验证参数是否符合预期

java 复制代码
import com.google.common.base.Preconditions;

public class PreconditionsDemo {

    public static void main(String[] args) {
        // 1. 检查参数非空
        try {
            checkNotNull(null);
        } catch (NullPointerException e) {
            System.out.println("checkNotNull 异常: " + e.getMessage());
        }

        // 2. 检查条件为 true
        try {
            checkArgument(false, "参数不合法");
        } catch (IllegalArgumentException e) {
            System.out.println("checkArgument 异常: " + e.getMessage());
        }

        // 3. 检查状态
        try {
            checkState(false, "状态错误");
        } catch (IllegalStateException e) {
            System.out.println("checkState 异常: " + e.getMessage());
        }

        // 正常情况
        System.out.println("正常执行: " + checkNotNull("正常值"));
    }

    public static <T> T checkNotNull(T obj) {
        return Preconditions.checkNotNull(obj, "对象不能为空");
    }

    public static void checkArgument(boolean condition, String message) {
        Preconditions.checkArgument(condition, message);
    }

    public static void  checkState(boolean state, String message) {
        Preconditions.checkState(state, message);
    }
}

运行结果

java 复制代码
checkNotNull 异常: 对象不能为空
checkArgument 异常: 参数不合法
checkState 异常: 状态错误
正常执行: 正常值

4. 函数式编程

4.1 Functions 与 Predicates

Functions 提供了函数式编程的支持,Predicates 提供了断言/谓词功能

java 复制代码
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.List;

public class FunctionPredicateDemo {

    public static void main(String[] args) {
        // ===== Functions =====

        // 1. 函数组合 - compose
        Function<String, Integer> composed = Functions.compose(
                String::length,  //第二个执行:计算长度
                String::trim   // 第一个执行,去掉空格
        );
        System.out.println("函数组合: " + composed.apply("  abc  "));
        // 输出: 3

        // 2. Map 转换
        List<String> names = Arrays.asList("Tom", "Jerry", "Mike");
        List<Integer> lengths = Lists.transform(names, String::length);
        System.out.println("Map转换: " + lengths);
        // 输出: [3, 5, 4]

        // ===== Predicates =====
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 3. 基本断言
        Predicate<Integer> isEven = n -> n % 2 == 0;

        // 4. 过滤集合
        List<Integer> evens = Lists.newArrayList(Iterables.filter(numbers, isEven));
        System.out.println("偶数: " + evens);
        // 输出: [2, 4, 6, 8, 10]

        // 5. 断言组合 - and
        Predicate<Integer> isEvenAndGreaterThan5 = Predicates.and(
                isEven,
                n -> n > 5
        );
        List<Integer> result1 = Lists.newArrayList(Iterables.filter(numbers, isEvenAndGreaterThan5));
        System.out.println("偶数且大于5: " + result1);
        // 输出: [6, 8, 10]

        // 6. 判断是否满足条件
        System.out.println("全部偶数? " + Iterables.all(numbers, isEven));
        System.out.println("包含偶数? " + Iterables.any(numbers, isEven));
        // 输出: false, true

        // 7. find - 查找第一个匹配的
        Integer found = Iterables.find(numbers, isEven);
        System.out.println("第一个偶数: " + found);
        // 输出: 2
    }
}
4.2 Suppliers 供应者模式

Suppliers 提供了延迟加载/缓存功能,是实现懒加载和缓存的利器

java 复制代码
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import java.util.concurrent.TimeUnit;

public class SuppliersDemo {

    public static void main(String[] args) throws Exception {
        // 1. 基础 Supplier
        Supplier<String> supplier = new Supplier<String>() {
            @Override
            public String get() {
                System.out.println("Supplier 被调用...");
                return "Hello Guava";
            }
        };

        System.out.println("调用1: " + supplier.get());
        System.out.println("调用2: " + supplier.get());

        System.out.println("=================");

        // 2. Memoizing Supplier (记忆化 - 缓存结果)
        Supplier<String> memoizingSupplier = Suppliers.memoize(supplier);

        System.out.println("Memoizing 调用1: " + memoizingSupplier.get());
        System.out.println("Memoizing 调用2: " + memoizingSupplier.get());

        System.out.println("=================");

        // 3. ExpiringMemoizingSupplier (带过期时间)
        Supplier<String> expiringSupplier = Suppliers.memoizeWithExpiration(
                () -> {
                    System.out.println("ExpiringSupplier 被调用...");
                    return "Expiring: " + System.currentTimeMillis();
                },
                2, // 2秒后过期
                TimeUnit.SECONDS
        );

        System.out.println("过期缓存 调用1: " + expiringSupplier.get());
        Thread.sleep(1000);
        System.out.println("过期缓存 调用2: " + expiringSupplier.get());
        Thread.sleep(1500);
        System.out.println("过期缓存 调用3: " + expiringSupplier.get());
    }
}

运行效果

java 复制代码
Supplier 被调用...
调用1: Hello Guava
Supplier 被调用...
调用2: Hello Guava
=================
Supplier 被调用...
Memoizing 调用1: Hello Guava
Memoizing 调用2: Hello Guava
=================
ExpiringSupplier 被调用...
过期缓存 调用1: Expiring: 170...
过期缓存 调用2: Expiring: 170...  (未过期,不调用)
ExpiringSupplier 被调用...  (已过期,重新调用)
过期缓存 调用3: Expiring: 170...

5. 集合增强

5.1 不可变集合

Guava 提供了不可变集合(Immutable Collections),一旦创建就不能修改,可以安全地在多线程环境中使用。

java 复制代码
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.List;

public class ImmutableCollectionsDemo {

    public static void main(String[] args) {
        // 1. 创建不可变 List
        ImmutableList<String> immutableList = ImmutableList.of("A", "B", "C", "D");
        System.out.println("ImmutableList: " + immutableList);
        // 输出: [A, B, C, D]

        // 2. 不可变 List 特性 - 不能修改
        try {
            immutableList.add("E");  // 抛出 UnsupportedOperationException
        } catch (UnsupportedOperationException e) {
            System.out.println("不能添加: true");
        }

        // 3. 使用 Builder 创建
        ImmutableList<String> builderList = ImmutableList.<String>builder()
                .add("a")
                .add("b")
                .addAll(immutableList)
                .build();
        System.out.println("Builder创建: " + builderList);
        // 输出: [a, b, A, B, C, D]

        // 4. 不可变 Set
        ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 4, 5);

        // 5. 不可变 Map
        ImmutableMap<String, Integer> immutableMap = ImmutableMap.of(
                "one", 1,
                "two", 2,
                "three", 3
        );
        System.out.println("ImmutableMap: " + immutableMap);
        // 输出: {one=1, two=2, three=3}
    }
}
5.2 Multimap 多值映射

Multimap 允许一个 key 对应多个 value,解决了 Map<K, List> 的繁琐操作

java 复制代码
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;

public class MultimapDemo {

    public static void main(String[] args) {
        // 1. 基本使用 - ArrayListMultimap
        Multimap<String, String> multimap = ArrayListMultimap.create();

        // 添加值 (一个 key 对应多个 value)
        multimap.put("水果", "苹果");
        multimap.put("水果", "香蕉");
        multimap.put("水果", "橙子");
        multimap.put("蔬菜", "白菜");
        multimap.put("蔬菜", "萝卜");

        System.out.println("所有映射: " + multimap);
        // 输出: {水果=[苹果, 香蕉, 橙子], 蔬菜=[白菜, 萝卜]}

        // 2. 获取单个 key 的所有值
        Collection<String> fruits = multimap.get("水果");
        System.out.println("水果: " + fruits);
        // 输出: [苹果, 香蕉, 橙子]

        // 3. 获取不存在的 key
        Collection<String> notExist = multimap.get("不存在");
        System.out.println("不存在的key: " + notExist);
        // 输出: [] (返回空集合,不是 null)

        // 4. HashMultimap - value 不重复
        HashMultimap<String, String> hashMultimap = HashMultimap.create();
        hashMultimap.put("标签", "Java");
        hashMultimap.put("标签", "Java");  // 重复,不会添加
        hashMultimap.put("标签", "Python");

        System.out.println("HashMultimap: " + hashMultimap.get("标签"));
        // 输出: [Java, Python]
    }
}
5.3 BiMap 双向映射

BiMap 实现了 Key-Value 的双向映射,可以通过 value 获取 key

java 复制代码
import com.google.common.collect.EnumHashBiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.EnumBiMap;

public class BiMapDemo {

    public static void main(String[] args) {
        // 1. 基本使用 - HashBiMap
        HashBiMap<String, String> biMap = HashBiMap.create();

        biMap.put("CN", "中国");
        biMap.put("US", "美国");
        biMap.put("JP", "日本");

        System.out.println("正向: " + biMap);
        // 输出: {CN=中国, US=美国, JP=日本}

        // 2. 反向获取
        System.out.println("反向-中国: " + biMap.inverse().get("中国"));
        System.out.println("反向-美国: " + biMap.inverse().get("美国"));
        // 输出: CN, US

        // 3. 通过 value 获取 key
        String countryKey = biMap.inverse().get("日本");
        System.out.println("通过value获取key: " + countryKey);
        // 输出: JP

        // 4. forcePut 强制覆盖
        biMap.forcePut("CN", "中华人民共和国");
        System.out.println("强制覆盖后: " + biMap);

        // 5. value 不能重复 (会抛出异常)
        try {
            biMap.put("CN2", "中华人民共和国");  // 抛出 IllegalArgumentException
        } catch (Exception e) {
            System.out.println("Value重复异常: " + e.getMessage());
        }

        System.out.println("=================");

        // 6. EnumBiMap - 枚举类型
        EnumHashBiMap<Status, String> enumHashBiMap = EnumHashBiMap.create(Status.class);
        enumHashBiMap.put(Status.ACTIVE, "激活");
        enumHashBiMap.put(Status.INACTIVE, "未激活");
        System.out.println("EnumHashBiMap: " + enumHashBiMap);
        System.out.println("通过value获取key: " + enumHashBiMap.inverse().get("激活"));
    }

    enum Status {
        ACTIVE, INACTIVE
    }
}
5.4 Table 表格结构

Table 提供了类似 Excel 表格的数据结构,适合存储二维关系数据

java 复制代码
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.util.Map;
import java.util.Set;

public class TableDemo {

    public static void main(String[] args) {
        // 1. 创建 Table
        Table<String, String, Integer> table = HashBasedTable.create();

        // 2. 添加数据 (行, 列, 值)
        table.put("张三", "语文", 85);
        table.put("张三", "数学", 90);
        table.put("张三", "英语", 88);

        table.put("李四", "语文", 92);
        table.put("李四", "数学", 78);
        table.put("李四", "英语", 95);

        System.out.println("表格数据: " + table);

        // 3. 获取某个学生的所有成绩
        Map<String, Integer> zhangScores = table.row("张三");
        System.out.println("张三成绩: " + zhangScores);
        // 输出: {语文=85, 数学=90, 英语=88}

        // 4. 获取某一科目的所有成绩
        Map<String, Integer> chineseScores = table.column("语文");
        System.out.println("语文成绩: " + chineseScores);
        // 输出: {张三=85, 李四=92}

        // 5. 获取某个具体值
        Integer score = table.get("张三", "数学");
        System.out.println("张三数学: " + score);
        // 输出: 90



    }
}

6. 本地缓存

6.1 缓存构建器模式

Guava Cache 使用构建器模式来配置缓存,语法清晰灵活

java 复制代码
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;

public class CacheBuilderDemo {

    public static void main(String[] args) throws Exception {
        // 1. 基本构建
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(100)           // 最大缓存数量
                .expireAfterWrite(10, TimeUnit.MINUTES)  // 写入后10分钟过期
                .build();

        cache.put("key1", "value1");
        System.out.println("基本缓存: " + cache.getIfPresent("key1"));

        // 2. 基于容量的淘汰
        Cache<String, String> sizeCache = CacheBuilder.newBuilder()
                .maximumSize(2)
                .build();

        sizeCache.put("a", "1");
        sizeCache.put("b", "2");
        sizeCache.put("c", "3");  // 超过容量,会淘汰最早的

        System.out.println("容量淘汰 a=" + sizeCache.getIfPresent("a"));
        System.out.println("容量淘汰 c=" + sizeCache.getIfPresent("c"));
        // 输出: null, 3

        // 3. 基于权重的淘汰
        Cache<String, String> weightCache = CacheBuilder.newBuilder()
                .maximumWeight(100)
                .weigher((String key, String value) -> key.length() + value.length())
                .build();

        weightCache.put("xx", "yy");  // 权重为4
        weightCache.put("longkey", "longvalue");// 权重为16

        System.out.println("容量淘汰 xx=" + sizeCache.getIfPresent("xx"));


        System.out.println("权重淘汰后数量: " + weightCache.size());
    }
}
6.2 缓存使用
java 复制代码
import com.google.common.cache.*;
import java.util.concurrent.TimeUnit;

public class CacheUseDemo {

    public static void main(String[] args) throws Exception {
        // 1. 手动加载
        Cache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(10)
                .build();

        cache.put("key1", "value1");
        System.out.println("getIfPresent: " + cache.getIfPresent("key1"));

        // 2. 自动加载 - get(key, loader)
        String value = cache.get("key2", () -> {
            System.out.println("从数据库加载...");
            return "database_value";
        });
        System.out.println("自动加载: " + value);

        // 3. LoadingCache - 预定义的自动加载缓存
        LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
                .maximumSize(10)
                .build(new CacheLoader<String, String>() {
                    @Override
                    public String load(String key) throws Exception {
                        return "loaded_" + key;
                    }
                });

        // 4. 缓存过期时间
        Cache<String, String> expireCache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(1, TimeUnit.SECONDS)   // 写入后过期
                .expireAfterAccess(2, TimeUnit.SECONDS) // 访问后过期
                .build();

        expireCache.put("expire", "test");
        System.out.println("写入后立即获取: " + expireCache.getIfPresent("expire"));
        Thread.sleep(1500);
        System.out.println("写入1.5秒后获取: " + expireCache.getIfPresent("expire"));

        // 5. 统计信息
        Cache<String, String> statsCache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .recordStats()  // 开启统计
                .build();

        statsCache.put("a", "1");
        statsCache.getIfPresent("a");
        statsCache.getIfPresent("nonexistent");

        CacheStats stats = statsCache.stats();
        System.out.println("命中率: " + stats.hitRate());
        System.out.println("请求次数: " + stats.requestCount());
    }
}

7. EventBus 事件总线

7.1 同步事件总线

EventBus 是 Guava 提供的发布-订阅模式的事件总线

java 复制代码
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

public class EventBusDemo {

    public static void main(String[] args) {
        // 1. 创建事件总线
        EventBus eventBus = new EventBus("myEventBus");

        // 2. 注册订阅者
        eventBus.register(new OrderEventListener());
        eventBus.register(new PaymentEventListener());

        // 3. 发布事件
        System.out.println("发布订单事件:");
        eventBus.post(new OrderEvent("订单-001", 100.0));

        System.out.println("发布支付事件:");
        eventBus.post(new PaymentEvent("支付-001", "支付宝"));
    }

    // 事件类
    static class OrderEvent {
        private String orderId;
        private double amount;

        public OrderEvent(String orderId, double amount) {
            this.orderId = orderId;
            this.amount = amount;
        }

        public String getOrderId() { return orderId; }
        public double getAmount() { return amount; }
    }

    static class PaymentEvent {
        private String paymentId;
        private String method;

        public PaymentEvent(String paymentId, String method) {
            this.paymentId = paymentId;
            this.method = method;
        }

        public String getPaymentId() { return paymentId; }
        public String getMethod() { return method; }
    }

    // 订单事件监听器
    static class OrderEventListener {
        @Subscribe
        public void handleOrderEvent(OrderEvent event) {
            System.out.println("  [OrderListener] 收到订单: " + event.getOrderId()
                    + ", 金额: " + event.getAmount());
        }
    }

    // 支付事件监听器
    static class PaymentEventListener {
        @Subscribe
        public void handlePaymentEvent(PaymentEvent event) {
            System.out.println("  [PaymentListener] 收到支付: " + event.getPaymentId()
                    + ", 方式: " + event.getMethod());
        }
    }
}
7.2 异步事件总线

AsyncEventBus 是异步事件总线,适用于耗时操作

java 复制代码
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.Subscribe;
import java.util.concurrent.*;

public class AsyncEventBusDemo {

    public static void main(String[] args) throws Exception {
        // 1. 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(4);

        // 2. 创建异步事件总线
        AsyncEventBus asyncEventBus = new AsyncEventBus(executor);

        // 3. 注册订阅者
        asyncEventBus.register(new AsyncEventListener());

        // 4. 发布事件 (异步执行)
        System.out.println("发布异步事件1:");
        asyncEventBus.post(new AsyncEvent("事件-A", 1));

        System.out.println("发布异步事件2:");
        asyncEventBus.post(new AsyncEvent("事件-B", 2));

        // 等待异步任务完成
        Thread.sleep(2000);
        System.out.println("主线程结束");

        executor.shutdown();
    }

    static class AsyncEvent {
        private String name;
        private int id;

        public AsyncEvent(String name, int id) {
            this.name = name;
            this.id = id;
        }

        public String getName() { return name; }
        public int getId() { return id; }
    }

    static class AsyncEventListener {
        @Subscribe
        public void handleAsyncEvent(AsyncEvent event) {
            System.out.println("  [AsyncListener] 处理: " + event.getName()
                    + " 线程: " + Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("  [AsyncListener] 完成: " + event.getName());
        }
    }
}

8. I/O 工具

8.1 文件操作
java 复制代码
import com.google.common.io.Files;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class FileDemo {

    public static void main(String[] args) throws Exception {
        // 1. 读取文件内容
        File tempFile = File.createTempFile("test", ".txt");
        Files.write("Hello Guava", tempFile, StandardCharsets.UTF_8);

        String content = Files.toString(tempFile, StandardCharsets.UTF_8);
        System.out.println("读取文件: " + content);

        // 2. 复制文件
        File destFile = new File(tempFile.getParent(), "copy.txt");
        Files.copy(tempFile, destFile);
        System.out.println("复制文件: " + destFile.exists());

        // 3. 移动文件
        File moveFile = new File(tempFile.getParent(), "move.txt");
        Files.move(tempFile, moveFile);
        System.out.println("移动文件: " + moveFile.exists());

        // 4. 读取行
        List<String> lines = Files.readLines(moveFile, StandardCharsets.UTF_8);
        System.out.println("读取行: " + lines);

        // 5. 文件操作
        File newFile = new File("new.txt");
        Files.touch(newFile);
        System.out.println("创建文件: " + newFile.exists());

        // 清理
        destFile.delete();
        moveFile.delete();
        newFile.delete();
    }
}
8.2 BaseEncoding 编解码
java 复制代码
import com.google.common.io.BaseEncoding;

public class BaseEncodingDemo {

    public static void main(String[] args) {
        // 1. Base64 编码
        String original = "Hello Guava! 你好";
        String base64 = BaseEncoding.base64().encode(original.getBytes());
        System.out.println("Base64编码: " + base64);

        // 2. Base64 解码
        String decoded = new String(BaseEncoding.base64().decode(base64));
        System.out.println("Base64解码: " + decoded);

        // 3. Base64 URL 安全编码
        String urlSafe = BaseEncoding.base64Url().encode(original.getBytes());
        System.out.println("Base64URL: " + urlSafe);

        // 4. 16进制编码
        String hex = BaseEncoding.base16().encode(original.getBytes());
        System.out.println("16进制编码: " + hex);

        // 5. 16进制解码
        String hexDecoded = new String(BaseEncoding.base16().decode(hex));
        System.out.println("16进制解码: " + hexDecoded);
    }
}

运行结果

java 复制代码
Base64编码: SGVsbG8gR3VavYeQ!
Base64解码: Hello Guava! 你好
Base64URL: SGVsbG8gR3VavYeQ
16进制编码: 48656C6C6F20475C7661E59B8E21
16进制解码: Hello Guava! 你好

9. 限流 RateLimiter

RateLimiter 是 Guava 提供的限流工具,基于令牌桶算法实现

java 复制代码
import com.google.common.util.concurrent.RateLimiter;
import java.util.concurrent.TimeUnit;

public class RateLimiterDemo {
    //基于令牌桶算法的限流器,允许在固定时间内处理一定数量的请求,超过限制的请求将被阻塞或拒绝。
    public static void main(String[] args) {
        // 1. 创建限流器 - 每秒产生 5 个令牌
        RateLimiter limiter = RateLimiter.create(5.0);

        System.out.println("=== 令牌桶限流 ===");

        // 2. 获取令牌 (阻塞等待)
        for (int i = 0; i < 10; i++) {
            double waitTime = limiter.acquire();
            System.out.println("第" + (i + 1) + "次获取令牌, 等待时间: "
                    + String.format("%.3f", waitTime) + "s");
        }

        System.out.println("==================");

        // 3. 尝试获取令牌 (非阻塞)
        RateLimiter tryLimiter = RateLimiter.create(10);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("=== 尝试获取令牌 ===");
        for (int i = 0; i < 15; i++) {
            boolean acquired = tryLimiter.tryAcquire(1);
            System.out.println("第" + (i + 1) + "次: " + (acquired ? "获取成功" : "获取失败"));
        }

    }
}

运行效果

java 复制代码
=== 令牌桶限流 ===
第1次获取令牌, 等待时间: 0.000s
第2次获取令牌, 等待时间: 0.198s
第3次获取令牌, 等待时间: 0.199s
第4次获取令牌, 等待时间: 0.199s
第5次获取令牌, 等待时间: 0.199s
第6次获取令牌, 等待时间: 0.199s
第7次获取令牌, 等待时间: 0.199s
第8次获取令牌, 等待时间: 0.199s
第9次获取令牌, 等待时间: 0.199s
第10次获取令牌, 等待时间: 0.199s
==================
=== 尝试获取令牌 ===
第1次: 获取成功
第2次: 获取成功
...
第15次: 获取失败
==================
=== 带超时获取 ===
第1次: 立即获取
第2次: 等待 0.499s 后获取
...
相关推荐
AI科技星7 小时前
全域数学公理:基于32维超复数与易经卦爻的宇宙大一统理论(整理版)
c语言·开发语言·线性代数·量子计算·agi
之歆8 小时前
DAY_13JavaScript DOM 操作完全指南:实战案例、性能优化与业务价值(下)
开发语言·前端·javascript·性能优化·ecmascript
Brilliantwxx8 小时前
【C++】深度剖析 · 继承 (虚基表+虚函数表)
开发语言·c++
砍材农夫8 小时前
物联网 基于netty构建mqtt协议规范(发布/订阅模式)
java·开发语言·物联网·netty
techdashen8 小时前
Rust 泛型 vs Java 泛型:它们看起来相似,但骨子里截然不同
java·开发语言·rust
一只旭宝8 小时前
【C加加入门精讲15】:IO流缓冲区、字符串流、缓冲流及STL vector容器零基础实战教程一、博客前言
开发语言·c++
AC赳赳老秦8 小时前
OpenClaw与Axure联动:自动生成原型图组件、批量修改原型样式,提升设计效率
python·web安全·ui·音视频·axure·photoshop·openclaw
EntyIU8 小时前
uv工程化项目指南
前端·python·uv
念恒123068 小时前
Python(while循环)
数据结构·python·算法