详解Java Google Guava

详细介绍

        Google Guava是Google为Java开发的开源库集合,它提供了丰富的工具类和集合框架的扩展,旨在提高开发效率和代码质量。Guava包括但不限于集合操作、并发编程辅助、缓存机制、字符串处理、I/O操作、原生类型支持、常见算法实现、函数式编程支持、测试库等模块。其核心设计原则是简化编程模型、减少代码量、提高代码的可读性和可维护性。

使用场景

1. 集合库增强

Guava提供了许多超越Java标准库的集合类,比如Multiset(多重集)、Multimap(多重映射)、ImmutableListImmutableSetImmutableMap等不可变集合,以及BiMap(双向映射)等。这些集合类型不仅丰富了数据结构的选择,还增强了代码的安全性,比如不可变集合确保了集合创建后不可被修改,这对于多线程环境特别有用。 

包括但不限于以下:

  • Immutable Collections(不可变集合):如ImmutableListImmutableSetImmutableMap等,提供线程安全且性能高效的不可变集合,适用于常量集合或集合的防御性拷贝。
  • Multiset/Multimap(多重集合/映射):允许一个键对应多个值,适合计数或元素去重等场景。
  • BiMap(双向映射):提供键值互查的能力,即可以从值反向获取键。
  • Table(表):类似于二维数组或映射的映射,支持行列键值。

2. 缓存机制

Guava Cache是实现本地缓存的一个强大工具。它支持自动过期、基于大小的驱逐策略、软引用和弱引用等多种特性,使得开发者可以很容易地实现高性能的数据缓存。通过自定义加载器和监听器,可以进一步定制缓存的行为,比如缓存项失效时的处理逻辑。

3. 并发工具

Guava提供了丰富的并发工具,如ListenableFutureService接口,用于异步编程和管理服务生命周期。ListenableFuture扩展了Java的Future接口,增加了回调功能,使得异步操作的结果处理更为灵活。而Service接口及其子类,如AbstractService,简化了服务的启动、停止和状态管理。

  • ListenableFuture:扩展了Java的Future接口,增加了回调机制,使得异步编程更加灵活。
  • Service框架:提供易于使用的服务生命周期管理工具,如ServiceAbstractService
  • RateLimiter:用于控制系统的吞吐量,实现限流功能。
  • 并发集合:如ConcurrentHashMultisetStriped64(用于低锁争用的计数器)等,提供了高性能的并发数据结构。

4. 原子操作与并发对象

Guava中的原子类,如AtomicDoubleAtomicLongMap等,提供了比Java标准库更丰富的原子操作支持。这些类在多线程环境下保证了高性能和线程安全的操作,特别是在计数器、标志位等场景下非常有用。

5. 字符串处理与预编译正则表达式

Guava提供了CharMatcherJoinerSplitter等工具,使得字符串操作更加高效和易于阅读。特别是CharMatcher,它提供了强大的字符匹配功能,而JoinerSplitter则分别简化了字符串的拼接和分割操作。此外,Guava还支持预编译正则表达式,通过PatternMatcher的封装,提高了正则表达式的复用性和执行效率。

例:

com.google.common.base.Strings类提供了很多实用的字符串处理方法,如isEmpty(), isNullOrEmpty(), commonPrefix(), commonSuffix()等,简化了字符串操作。

6. 函数式编程支持

虽然不及Java 8及以后版本中的Lambda表达式和Stream API那么直接,Guava提供了FunctionPredicateSupplier等接口,支持函数式编程风格,为Java 7及以下版本的开发者提供了函数式编程的便利。

7. 限流与资源管理

如开头提及,Guava的RateLimiter实现了令牌桶算法,是一种简单有效的限流工具,可以控制服务的访问速率,防止系统过载。这对于保护后端服务免受突发流量冲击尤为重要。

8. 其他实用工具

Guava还包括了很多其他实用工具,如Optional用于优雅地处理null值问题,RangeOrdering用于区间判断和排序,还有类型安全的构建器模式(Builder Pattern)等,这些都是提升代码质量的好帮手。

使用示例:

import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

public class GuavaUsageExample {
    public static void main(String[] args) {
        // 使用Preconditions进行参数检查
        String name = getUserName();
        Preconditions.checkNotNull(name, "用户名不能为空");

        // 使用ImmutableList创建不可变列表
        ImmutableList<String> users = ImmutableList.of("Alice", "Bob", "Charlie");

        // 创建一个简单的缓存
        LoadingCache<String, String> cache = CacheBuilder.newBuilder()
                .maximumSize(100)
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .build(
                        new CacheLoader<String, String>() {
                            public String load(String key) {
                                return createExpensiveObject(key);
                            }
                        });

        String value = cache.getUnchecked("key");
        
        // 异步执行任务
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
        ListenableFuture<String> future = executor.submit(() -> "Hello Guava");
    }

    private static String getUserName() {
        return "Alice";
    }

    private static String createExpensiveObject(String key) {
        // 模拟耗时操作
        return "Expensive Data for " + key;
    }
}

注意事项

1. 版本兼容性与依赖管理

  • 注意事项:Guava的更新较快,不同版本间可能存在API变更,导致项目升级时出现兼容性问题。
  • 示例:在Maven项目中使用特定版本的Guava,避免依赖冲突:
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version> <!-- 请替换为实际需要的版本 -->
</dependency>

使用<exclusions>标签排除其他库中可能引入的Guava冲突版本。

2. 性能与内存管理

  • 注意事项:合理使用不可变集合和其他高性能数据结构,注意它们对内存的影响。
  • 示例:使用ImmutableList时,避免频繁创建大量大型不可变集合,可能导致内存占用过高。
// 正确使用不可变集合,避免不必要的内存消耗
ImmutableList<String> names = ImmutableList.of("Alice", "Bob", "Charlie");

3. 并发编程中的异常处理

  • 注意事项:在使用ListenableFuture等并发工具时,确保异常得到妥善处理,避免任务执行失败后无响应。
  • 示例:使用Futures.addCallback来处理异步任务的完成和异常情况。
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<String> future = service.submit(() -> doSomething());
Futures.addCallback(future, new FutureCallback<String>() {
    @Override
    public void onSuccess(String result) {
        System.out.println("成功:" + result);
    }

    @Override
    public void onFailure(Throwable t) {
        System.err.println("失败:" + t.getMessage());
    }
});

4. 缓存策略选择

  • 注意事项:正确配置Guava Cache的大小、过期策略,避免内存泄漏。
  • 示例:合理设置缓存的最大大小和过期时间。
LoadingCache<String, ExpensiveObject> cache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterAccess(10, TimeUnit.MINUTES)
        .build(
                new CacheLoader<String, ExpensiveObject>() {
                    public ExpensiveObject load(String key) {
                        return createExpensiveObject(key);
                    }
                });

5. 避免过度封装

  • 注意事项:虽然Guava提供了很多高级抽象,但过度使用可能导致代码难以理解和维护。
  • 示例:在使用Guava的集合转换时,确保转换的必要性和清晰性。
// 明智地使用转换,保持代码的可读性
List<String> names = Lists.transform(originalList, item -> item.getName()); // 明确转换逻辑

6. 谨慎使用默认值

  • 注意事项:使用Optional等工具时,避免滥用默认值,以免掩盖潜在问题。
  • 示例:正确使用Optional来避免空指针异常,而不是直接使用默认值。
Optional<String> optional = Optional.ofNullable(getValue());
String value = optional.orElseThrow(() -> new IllegalStateException("Value is required"));

注意:在使用Google Guava时,开发者需综合考虑版本兼容性、性能优化、并发编程的正确性、资源管理、以及代码的可读性和可维护性等多个方面。通过上述示例,可以更好地理解如何在实际开发中运用Guava,同时避免常见陷阱,提升代码质量和应用程序的稳定性。

优缺点

优点

  1. 丰富的集合类:Guava提供了如ImmutableList, ImmutableSet, Multiset等,增强了Java集合框架,提高了代码的安全性和性能。

    // 使用ImmutableList创建不可变列表
    ImmutableList<String> names = ImmutableList.of("Alice", "Bob", "Charlie");
  2. 强大的缓存功能:Guava Cache提供了自动过期、大小限制、软引用/弱引用等功能,简化了缓存管理。

    LoadingCache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build(new CacheLoader<String, String>() {
                public String load(String key) {
                    return expensiveComputation(key);
                }
            });
  3. 并发工具:提供了线程池管理、Future扩展(ListenableFuture)、RateLimiter等,简化并发编程。

    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
    ListenableFuture<String> future = service.submit(() -> "Hello Guava");
  4. 实用工具类:如Strings、Preconditions、Objects等,提供了大量简洁、强大的工具方法,提升代码质量。

    String cleanName = Strings.nullToEmpty(dirtyName).trim();

缺点

  1. 学习曲线:Guava提供了大量的API,对于新手来说,可能需要一段时间去学习和熟悉。

    应对策略:建议分模块学习,先掌握最常用的功能,如集合、缓存,逐步深入。

  2. 版本兼容性:Guava更新频繁,新版本可能引入不兼容变更,影响现有代码。

    应对策略:项目升级Guava版本时,详细阅读版本更新日志,进行充分的测试,确保兼容性。

  3. 性能考虑:虽然Guava提供了高性能的数据结构和工具,但不恰当的使用也可能导致性能问题。

    应对策略:合理选择数据结构和工具类,进行性能测试,确保符合性能要求。

解决问题方案

1. 版本冲突问题

问题描述:在项目中引入Guava时,可能与其他第三方库依赖的Guava版本不一致,导致类路径冲突。

解决方案

  • 明确指定版本:在构建工具(如Maven或Gradle)的依赖配置中明确指定Guava的版本,确保项目统一使用一个版本。
  • 依赖排除:若第三方库自带了Guava依赖,可通过依赖排除功能排除该库自带的Guava版本,确保使用项目指定的版本。

示例

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>30.1-jre</version> <!-- 指定Guava版本 -->
    </dependency>
    <dependency>
        <groupId>some-third-party</groupId>
        <artifactId>library</artifactId>
        <version>1.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2. 缓存未按预期工作

问题描述:使用Guava Cache时,可能遇到缓存项没有按预期被加载、过期或被驱逐的情况。

解决方案

  • 检查配置:确保CacheBuilder的配置正确,如maximumSizeexpireAfterWriterefreshAfterWrite等。
  • 调试与监控:使用Cache.stats()方法获取统计信息,检查命中率、缺失率等,以诊断问题。

示例

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .removalListener(new RemovalListener<Key, Graph>() {
        public void onRemoval(RemovalNotification<Key, Graph> notification) {
            System.out.println(notification.getKey() + " was removed, cause: " + notification.getCause());
        }
    })
    .build(
        new CacheLoader<Key, Graph>() {
            public Graph load(Key key) throws AnyException {
                return createExpensiveGraph(key);
            }
        });

3. 并发编程中的异常丢失

问题描述:使用ListenableFutureService时,如果没有正确处理异常,可能导致异常被忽略,难以调试。

解决方案

  • 添加回调处理异常:使用Futures.addCallbackListenableFuture添加回调,确保异常能得到恰当处理。
  • 服务生命周期管理:正确实现Service.Listener来监听服务状态变化,包括异常情况。

示例

ListenableFuture<String> future = ...;
Futures.addCallback(future, new FutureCallback<String>() {
    @Override
    public void onSuccess(String result) {
        System.out.println("Success: " + result);
    }

    @Override
    public void onFailure(Throwable t) {
        System.err.println("Failure: " + t.getMessage());
        // 正确处理异常
    }
}, MoreExecutors.directExecutor());

4. 性能瓶颈

问题描述:尽管Guava提供了高效的工具,但在特定场景下仍可能出现性能瓶颈,如频繁的不可变集合创建、错误的缓存策略等。

解决方案

  • 性能分析:使用性能分析工具(如VisualVM或JProfiler)定位性能瓶颈。
  • 优化数据结构:根据具体需求选择合适的数据结构,比如在频繁修改的场景下,避免使用不可变集合。
  • 调整缓存策略:根据实际访问模式调整缓存大小、过期时间等,避免不必要的计算和内存占用。

         Guava是Java开发中非常有价值的工具库,它通过提供高级数据结构、并发工具、实用工具类等,极大地提高了开发效率和代码质量。然而,开发者在享受其便利的同时,也应注意其学习成本、版本兼容性和性能优化等问题,通过合理的使用策略和持续的学习,最大化Guava的效用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/609227.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣每日一题- 给植物浇水 II -2024.5.9

力扣题目&#xff1a;给植物浇水 II 题目链接: 2105.给植物浇水 II 题目描述 代码思路 根据题目内容&#xff0c;使用双指针从左右两边同时向中间移动&#xff0c;模拟浇水过程即可。 代码纯享版 class Solution {public int minimumRefill(int[] plants, int capacityA, …

FANUC机器人单轴零点标定时提示无法执行零点标定,由于重力补偿已启用,所有机器人轴的脉冲计数必须有效

FANUC机器人单轴零点标定时提示无法执行零点标定,由于重力补偿已启用,所有机器人轴的脉冲计数必须有效 首先,机器人由于长时间断电未使用,6个轴的编码器数据全部丢失,上电后报警SRVO-062, 有关SRVO-062故障报警的相关内容可参考以下链接: FANUC机器人SRVO-062报警原因分…

windows11如何设置无线网卡不休眠

为了在家里用向日葵等软件连接上公司的台式电脑&#xff0c;发现尴尬的事情&#xff1a;在家里连接时提示公司的电脑下线了。经排查&#xff0c;发现长时间不用时&#xff0c;公司的台式电脑的无线网卡休眠了。 windows11可以用下面的步骤设置无线网卡不休眠&#xff1a; 1. 设…

Sybase数据库分页查询(指定起始位置)

针对单表数据量过大的场景&#xff0c;分页查询必不可少。针对sybase数据库分页查询的案例全网稀少&#xff0c;特别是指定起始页的分页查询实现。 本文依靠实际开发场景&#xff0c;特此总结Sybase数据库分页查询&#xff08;指定起始位置&#xff09;。 目录 一、 SQL实现分…

SQL统计语句记录

1.达梦数据库 统计指定单位的12个月份的业务数据 SELECT a.DEPT_ID, b.dept_name, a.USER_NAME, count(a.dept_id) as count, sum(case when to_char(a.CREATE_TIME,yyyy-mm) 2023-01 THEN 1 else 0 end) as one,sum(case when to_char(a.CREATE_TIME,yyyy-mm) 2023-02 T…

JavaScript手写专题——图片懒加载、滚动节流、防抖手写

图片懒加载场景&#xff1a;在一些图片量比较大的网站&#xff08;比如电商网站首页&#xff0c;或者团购网站、小游戏首页等&#xff09;&#xff0c;如果我们尝试在用户打开页面的时候&#xff0c;就把所有的图片资源加载完毕&#xff0c;那么很可能会造成白屏、卡顿等现象&a…

内网安全-隧道技术SSHDNSICMPSMB上线通讯LinuxMac 简单总结

第126天&#xff1a;内网安全-隧道技术&SSH&DNS&ICMP&SMB&上线通讯Linux&Mac_内网安全-隧道技术_ssh_dns_icmp_smb_上线通讯linux_mac-CSDN博客 内网渗透—隧道技术_隧道技术csdn-CSDN博客 #SMB 隧道&通讯&上线 判断&#xff1a;445 通讯 上…

Azure Windows2012升级2016

Azure Windows2012升级2016 在自己电脑配置Azure PowerShell前置条件PowerShell 登录到 Azure Azure 中运行 Windows Server 的 VM 的就地升级前置条件&#xff0c;生成一块OS磁盘将生成的OS磁盘附件到需升级的服务器执行就地升级到 Windows Server 2016 升级后配置故障恢复 在…

一觉醒来 AI科技圈发生的大小事儿 05月09日

&#x1f4f3;AlphaFold 3 重磅问世&#xff0c;全面预测蛋白质与所有生命分子相互作用及结构&#xff0c;准确性远超以往水平 Google DeepMind发布了AlphaFold3模型&#xff0c;能够联合预测蛋白质、核酸、小分子等复合物结构&#xff0c;准确性显著提高&#xff0c;对跨生物…

代码随想录算法训练营第36期DAY22

DAY22 654最大二叉树 自己做的时候忽略了&#xff1a;nums.length>1的题给条件。所以每次递归都要判断是否size()>1&#xff0c;不要空的。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *rig…

让数据更「高效」一点!IvorySQL在Neon平台上的迅速部署和灵活应用

IvorySQL本身就是一个100%兼容PostgreSQL最新内核的开源数据库系统&#xff0c;而Neon Autoscaling Platform通常支持多种数据库和应用程序。将IvorySQL集成到该平台后&#xff0c;可以进一步增强与其他系统和应用程序的兼容性&#xff0c;同时更全面的体验IvorySQL的Oracle兼容…

深入探究 Spring Boot Starter:从概念到实践

序言 Spring Boot Starter 是 Spring Boot 生态系统中的一个核心概念&#xff0c;它为开发者提供了一种便捷的方式来捆绑和配置应用程序所需的依赖项。本文将深入探讨 Spring Boot Starter 的概念、原理以及如何创建自定义的 Starter。 一、什么是 Spring Boot Starter Spri…

docker 安装elasticsearch8.X

docker 安装elasticsearch8.X 安装elasticsearch8.X前言安装elasticsearch安装elasticsearch-analysis-ik安装kibana 安装elasticsearch8.X 前言 由于需要安装elasticsearch、IK分词插件、kibana。所以需要保持这三者的版本一致性。 elasticsearch 8.12.2 kibana 8.12.2 ela…

科沃斯梦碎“扫地茅”,钱东奇跌落“风口”

昔日“扫地茅“不香了&#xff0c;科沃斯跌落神坛。 4月27日&#xff0c;科沃斯发布2023年报显示&#xff1a;2023年&#xff0c;科沃斯的营收为155.02亿元&#xff0c;同比增加1.16%&#xff1b;同期&#xff0c;净利为6.10亿元&#xff0c;同比减少63.96%。科沃斯的经营业绩…

Mysql数据在磁盘上的存储结构

一. 前言 一行数据的存储格式大致如下所示: 变长字段的长度列表&#xff0c;null值列表&#xff0c;数据头&#xff0c;column01的值&#xff0c;column02的值&#xff0c;column0n的值… 二. 变长字段 在MySQL里有一些字段的长度是变长的&#xff0c;是不固定的&#xff0c;…

可视化-实验五-Pyecharts工具包的使用及文本数据可视化

1.2.1 pyecharts的数据类型以及新的数据导入逻辑 由于pyecharts背后封装的js库&#xff0c;会涉及到数据类型转化。它暂时要求输入数据必须是python的基础数据类型&#xff0c;比如字符串&#xff0c;列表&#xff0c;字典&#xff0c;而不能是序列这样的数据类型。因此序列输入…

RockChip Android13 添加/删除ListPreference方法

概述: 本章将讲述在Android添加或删除ListPreference的几种方法,并以EthernetSettingsActivity为例,添加/删除一项ListPreference: 默认效果图: 添加后效果图: 方法一: 1、全部添加xml 在Activity类中使用addPreferencesFromResource()方法解析XML文件并添加Prefere…

Node.js安装与配置环境 v20.13.1(LTS)

1 下载 Node.js — Run JavaScript Everywhere LTS -- long-term support&#xff0c;长期维护版本 如果要下载其他版本在download里选择下载 2 安装 一路点击next&#xff0c;默认安装路径C:\Program Files\nodejs 3 环境变量配置 1&#xff09;Path环境变量增加nodejs安装…

艾体宝方案 | 加密USB金融解决方案

在现代金融行业中&#xff0c;保护敏感数据和合规性已成为至关重要的任务。为了帮助金融公司应对移动性风险和合规挑战&#xff0c;我们提供了一种高效的加密USB解决方案。 一、为什么金融公司需要加密USB解决方案 1、降低移动性风险 金融服务公司正在迅速过渡到一种模式&a…

将本地托管模型与 Elastic AI Assistant 结合使用的好处

作者&#xff1a;来自 Elastic James Spiteri, Dhrumil Patel 当今公共部门组织利用生成式人工智能解决安全挑战的一种方式。 凭借其筛选大量数据以发现异常模式的能力&#xff0c;生成式人工智能现在在帮助团队保护其组织免受网络威胁方面发挥着关键作用。 它还可以帮助安全专…