提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)

简介: 提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)

Guava库是一组来自Google的核心Java库,其设计目的是为了简化Java开发过程,提高开发效率。这个库包含了大量实用的API,可以帮助开发者解决日常开发中遇到的各种问题。


提升编程效率的利器: 解析Google Guava库之集合篇Immutable(一)

提升编程效率的利器: 解析Google Guava库之集合篇Multimap(二)

提升编程效率的利器: 解析Google Guava库之集合篇BitMap(三)

提升编程效率的利器: 解析Google Guava库之集合篇Table二维映射(四)

提升编程效率的利器: 解析Google Guava库之集合篇RangeSet范围集合(五)

提升编程效率的利器: 解析Google Guava库之集合篇RangeMap范围映射(六)

一、源码包的分布

Guava库的源码包分布非常广泛,覆盖了多个不同的功能领域。以下是一些主要的源码包及其功能:

com.google.common.base:这个包包含了基本工具类库和接口,提供了一些通用的功能,如Preconditions(用于参数校验)、Optional(用于处理可能为null的值)等。

com.google.common.collect:这个包提供了带泛型的集合接口扩展和实现,以及工具类。它增加了一些Java标准库中没有的集合类型,如Multimap(多映射)、Multiset(多集)等,还提供了一些用于操作集合的实用方法。

com.google.common.eventbus:这个包实现了一个发布-订阅风格的事件总线,允许在不同组件之间发布和订阅事件,实现松耦合的通信。

com.google.common.hash:这个包提供了哈希工具类,用于计算哈希值和处理哈希相关的操作。

com.google.common.io:这个包包含了I/O工具类,提供了一些简化I/O操作的实用方法,如文件读写、字节流处理等。

com.google.common.math:这个包提供了原始算术类型和超大数的运算工具类,用于进行数学计算和处理大数字。

com.google.common.net:这个包包含了网络工具类,提供了一些与网络相关的实用功能,如URL处理、网络地址解析等。

com.google.common.primitives:这个包提供了对八种原始类型和无符号类型的静态工具类,包括一些基本类型的操作、转换和比较。

com.google.common.reflect:这个包包含了反射工具类,提供了一些用于反射操作的实用方法,如获取类信息、调用方法等。

com.google.common.util.concurrent:这个包提供了多线程工具类,包括一些并发编程的实用功能,如异步计算、线程池管理等。


这些源码包构成了Guava库的核心,提供了丰富的功能和工具类,方便开发者进行Java开发。通过使用Guava库,开发者可以更加高效地处理集合、缓存、并发编程、字符串处理、I/O操作等各种常见的开发任务。

二、字符处理工具

import com.google.common.base.CharMatcher;  
import com.google.common.base.Joiner;  
import com.google.common.base.Splitter;  
import com.google.common.base.Strings;  
import com.google.common.io.CharStreams;  
  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.nio.charset.Charset;  
  
public class GuavaDemo {  
  
    public static void main(String[] args) throws IOException {  
        // 1.使用Joiner拼接字符串  
        String joinedString = Joiner.on(", ").join("apple", "banana", "cherry");  
        System.out.println(joinedString); // 输出: apple, banana, cherry  
  
        // 2.使用Splitter拆分字符串  
        Iterable<String> splitStrings = Splitter.on(",").trimResults().split(joinedString);  
        for (String s : splitStrings) {  
            System.out.println(s); // 输出: apple, banana, cherry(每行一个)  
        }  
  
        // 3.使用Strings处理字符串  
        String nullString = null;  
        String emptyString = "";  
        String whitespaceString = "   ";  
        System.out.println(Strings.nullToEmpty(nullString)); // 输出: (空字符串)  
        System.out.println(Strings.isNullOrEmpty(emptyString)); // 输出: true  
        System.out.println(Strings.isNullOrEmpty(whitespaceString)); // 输出: false  
        System.out.println(CharMatcher.whitespace().removeFrom(whitespaceString)); // 输出: (空字符串)  
  
        // 4.使用Charsets指定字符集  
        Charset utf8 = Charsets.UTF_8;  
        try (InputStream inputStream = GuavaDemo.class.getResourceAsStream("/test.txt");  
             InputStreamReader reader = new InputStreamReader(inputStream, utf8)) {  
  
            String content = CharStreams.toString(reader);  
            System.out.println(content); // 输出: test.txt文件的内容(假设文件存在且为UTF-8编码)  
        }  

         // 5.原始字符串,采用驼峰式命名  
        String camelCaseString = "ExampleClassName";  
  
        // 转换为下划线式命名  
        String lowerUnderscoreString = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, camelCaseString);  
  
        // 打印转换后的字符串  
        System.out.println(lowerUnderscoreString); // 输出:example_class_name  
  
        // 如果要将下划线式命名转回驼峰式命名,可以这样做:  
        String backToCamelCaseString = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, lowerUnderscoreString);  
  
        // 打印转回驼峰式命名后的字符串  
        System.out.println(backToCamelCaseString); // 输出:ExampleClassName  

        // 6. 使用CharMatcher  
        String input = "Hello, World! This is a test string.";  
  
        // 使用CharMatcher移除指定字符  
        String resultWithoutVowels = CharMatcher.is('a', 'e', 'i', 'o', 'u').removeFrom(input);  
        // 打印结果: "Hll, Wrld! Ths s s tst strng."  
        System.out.println(resultWithoutVowels);  
  
        // 使用CharMatcher替换指定字符  
        String resultReplaceVowels = CharMatcher.is('a', 'e', 'i', 'o', 'u').replaceFrom(input, '*');  
        // 打印结果: "H*ll*, W*rld! Th*s *s * t*st str*ng."  
        System.out.println(resultReplaceVowels);  
  
        // 使用CharMatcher保留指定字符  
        String resultKeepVowels = CharMatcher.is('a', 'e', 'i', 'o', 'u').retainFrom(input);  
        // 打印结果: "eiooeiae"  
        System.out.println(resultKeepVowels);  
  
        // 7.使用CharSequences查找子序列的索引  
        int indexOfTest = CharSequences.indexOf(input, "test");  
        // 打印结果: 索引位置 21  
        System.out.println("索引位置: " + indexOfTest);  
  
        // 使用CharSequences比较两个CharSequence  
        boolean areEqual = CharSequences.equals("Hello", "Hello");  
        // 打印结果: true  
        System.out.println("两个序列是否相等: " + areEqual);  
  
        // 使用CharSequences拼接CharSequence  
        String concatenated = CharSequences.concat("Guava ", "is ", "awesome!").toString();  
        // 打印结果: "Guava is awesome!"  
        System.out.println(concatenated);  
    }  
}

Joiner 被用来将一个字符串列表以逗号加空格为分隔符合并成一个字符串。

Splitter 被用来根据逗号拆分合并后的字符串,并移除了结果字符串两端的空白字符。

Strings 类中的方法被用来处理空字符串和空白字符。nullToEmpty 方法将 null 转换为空字符串,isNullOrEmpty 方法检查字符串是否为 null 或空,CharMatcher 的 whitespace().removeFrom 方法移除了字符串中的所有空白字符。

Charsets 被用来获取 UTF-8 字符集,并通过 InputStreamReader 和 CharStreams 来读取和转换文件内容。

三、原始类型工具

Ints, Longs, Doubles, Floats, Booleans, Bytes, Shorts, Chars, 和 PrimitiveArrays 是 Guava 库中提供的一组用于操作原始类型数据的实用工具类。以下是一些使用这些类的示例:

import com.google.common.primitives.Booleans;  
import com.google.common.primitives.Bytes;  
import com.google.common.primitives.Chars;  
import com.google.common.primitives.Doubles;  
import com.google.common.primitives.Floats;  
import com.google.common.primitives.Ints;  
import com.google.common.primitives.Longs;  
import com.google.common.primitives.Shorts;  
import java.util.Arrays;  
  
public class GuavaPrimitivesExample {  
  
    public static void main(String[] args) {  
        // Ints 示例  
        int[] intArray = {1, 2, 3, 4, 5};  
        int sumOfInts = Ints.sum(intArray);  
        // 打印结果: 15  
        System.out.println("Sum of ints: " + sumOfInts);  
  
        // Longs 示例  
        long[] longArray = {1L, 2L, 3L, 4L, 5L};  
        long sumOfLongs = Longs.sum(longArray);  
        // 打印结果: 15  
        System.out.println("Sum of longs: " + sumOfLongs);  
  
        // Doubles 示例  
        double[] doubleArray = {1.1, 2.2, 3.3, 4.4, 5.5};  
        double sumOfDoubles = Doubles.sum(doubleArray);  
        // 打印结果: 16.5  
        System.out.println("Sum of doubles: " + sumOfDoubles);  
  
        // Floats 示例  
        float[] floatArray = {1.1f, 2.2f, 3.3f, 4.4f, 5.5f};  
        float sumOfFloats = Floats.sum(floatArray);  
        // 打印结果: 16.5  
        System.out.println("Sum of floats: " + sumOfFloats);  
  
        // Booleans 示例  
        boolean[] booleanArray = {true, false, true};  
        boolean anyTrue = Booleans.contains(booleanArray, true);  
        // 打印结果: true  
        System.out.println("Array contains true: " + anyTrue);  
  
        // Bytes 示例  
        byte[] byteArray = {1, 2, 3, 4, 5};  
        byte minByte = Bytes.min(byteArray);  
        // 打印结果: 1  
        System.out.println("Min byte: " + minByte);  
  
        // Shorts 示例  
        short[] shortArray = {1, 2, 3, 4, 5};  
        short maxShort = Shorts.max(shortArray);  
        // 打印结果: 5  
        System.out.println("Max short: " + maxShort);  
  
        // Chars 示例  
        char[] charArray = {'a', 'b', 'c', 'd', 'e'};  
        int charCount = Chars.count(charArray, 'c');  
        // 打印结果: 1  
        System.out.println("Count of 'c': " + charCount);  
  
        // 排序示例(使用Java标准库的Arrays.sort而不是Guava)  
        int[] unsortedIntArray = {5, 3, 1, 4, 2};  
        Arrays.sort(unsortedIntArray);  
        // 打印结果: [1, 2, 3, 4, 5]  
        System.out.println("Sorted int array: " + Arrays.toString(unsortedIntArray));  
    }  
}

四、IO工具类

包括 InputSupplier, OutputSupplier, Resources, ByteStreams, 和 CharStreams,它们主要用于简化输入/输出操作和流处理。以下是如何使用这些工具类的示例:

import com.google.common.base.Charsets;  
import com.google.common.base.Supplier;  
import com.google.common.io.ByteStreams;  
import com.google.common.io.CharStreams;  
import com.google.common.io.InputSupplier;  
import com.google.common.io.OutputSupplier;  
import com.google.common.io.Resources;  
  
import java.io.ByteArrayInputStream;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.io.Reader;  
import java.io.StringReader;  
import java.io.StringWriter;  
import java.net.URL;  
  
public class GuavaIoExample {  
  
    public static void main(String[] args) throws IOException {  
        // InputSupplier 示例  
        InputSupplier<InputStream> inputSupplier = new InputSupplier<InputStream>() {  
            @Override  
            public InputStream getInput() throws IOException {  
                return new ByteArrayInputStream("Hello, Guava!".getBytes(Charsets.UTF_8));  
            }  
        };  
  
        // 读取 InputSupplier 并转换为字符串  
        String fromInputSupplier = new String(ByteStreams.toByteArray(inputSupplier.getInput()), Charsets.UTF_8);  
        // 打印结果: Hello, Guava!  
        System.out.println("From InputSupplier: " + fromInputSupplier);  
  
        // OutputSupplier 示例  
        OutputSupplier<OutputStream> outputSupplier = new OutputSupplier<OutputStream>() {  
            @Override  
            public OutputStream getOutput() throws IOException {  
                return new ByteArrayOutputStream();  
            }  
        };  
  
        // 写入数据到 OutputSupplier 并获取结果  
        OutputStream outputStream = outputSupplier.getOutput();  
        outputStream.write("Hello, from OutputSupplier!".getBytes(Charsets.UTF_8));  
        ((ByteArrayOutputStream) outputStream).close(); // 对于 ByteArrayOutputStream,需要手动关闭以完成写入  
  
        // 注意:上面的代码片段实际上是有问题的,因为我们在外部关闭了流,但OutputSupplier的使用者通常期望自己关闭它。  
        // 正确的做法是,如果你控制了流的生命周期,不要让OutputSupplier返回它直到你准备好让调用者关闭它。  
        // 我们只是为了演示,实际上应该避免这样做。  
  
        // Resources 示例:从URL读取内容  
        URL url = Resources.getResource("somefile.txt"); // 假设 somefile.txt 在类路径上  
        String fromResources = Resources.toString(url, Charsets.UTF_8);  
        // 打印文件内容(取决于 somefile.txt 的实际内容)  
        System.out.println("From Resources: " + fromResources);  
  
        // ByteStreams 示例:从输入流复制到输出流  
        InputStream inputStream = new ByteArrayInputStream("Data to copy".getBytes(Charsets.UTF_8));  
        OutputStream copyOutputStream = new ByteArrayOutputStream();  
        ByteStreams.copy(inputStream, copyOutputStream);  
        String copiedData = new String(((ByteArrayOutputStream) copyOutputStream).toByteArray(), Charsets.UTF_8);  
        // 打印结果: Data to copy  
        System.out.println("Copied Data: " + copiedData);  
  
        // CharStreams 示例:从 Reader 读取所有字符  
        Reader reader = new StringReader("Characters to read");  
        String fromCharStreams = CharStreams.toString(reader);  
        // 打印结果: Characters to read  
        System.out.println("From CharStreams: " + fromCharStreams);  
  
        // 使用 try-with-resources 确保流正确关闭  
        try (StringWriter stringWriter = new StringWriter()) {  
            // 写入数据到 StringWriter  
            stringWriter.write("Hello, try-with-resources!");  
            // 从 StringWriter 获取数据  
            String writtenData = stringWriter.toString();  
            // 打印结果: Hello, try-with-resources!  
            System.out.println("Written Data: " + writtenData);  
        } // 在这里,StringWriter 会自动关闭,因为我们在 try-with-resources 语句中使用了它  
    }  
}

注意:在实际中应该避免像上面示例中那样手动关闭流,特别是当使用像 OutputSupplier 这样的构造时。通常,流的关闭应该由最终使用它的代码来处理,或者使用 try-with-resources 语句来自动管理资源。

五、其他常用的工具类

下面是 Guava 中 Stopwatch, ClassPath, BaseEncoding, Throwables, 和 HashCode 的使用示例:

import com.google.common.base.Charsets;  
import com.google.common.base.Throwables;  
import com.google.common.hash.HashCode;  
import com.google.common.hash.Hashing;  
import com.google.common.io.BaseEncoding;  
import com.google.common.io.ClassPath;  
import com.google.common.primitives.Bytes;  
import com.google.common.util.concurrent.Uninterruptibles;  
  
import java.io.IOException;  
import java.io.InputStream;  
import java.net.URL;  
import java.util.concurrent.TimeUnit;  
  
public class GuavaUtilitiesExample {  
  
    public static void main(String[] args) {  
        // Stopwatch 示例:测量代码执行时间  
        Stopwatch stopwatch = Stopwatch.createStarted();  
        Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); // 模拟耗时操作  
        long elapsedMillis = stopwatch.elapsed(TimeUnit.MILLISECONDS);  
        // 打印结果:耗时约 1000 毫秒  
        System.out.println("Elapsed time: " + elapsedMillis + " ms");  
  
        // ClassPath 示例:遍历类路径上的资源  
        try {  
            ClassPath classPath = ClassPath.from(GuavaUtilitiesExample.class.getClassLoader());  
            for (ClassPath.ClassInfo classInfo : classPath.getAllClasses()) {  
                if (classInfo.getName().contains("Guava")) {  
                    // 打印结果:包含 "Guava" 的类名  
                    System.out.println("Class found: " + classInfo.getName());  
                }  
            }  
        } catch (IOException e) {  
            Throwables.throwIfUnchecked(e); // 传播未检查的异常  
        }  
  
        // BaseEncoding 示例:编码和解码  
        String originalText = "Hello, Guava!";  
        String encodedText = BaseEncoding.base64().encode(originalText.getBytes(Charsets.UTF_8));  
        byte[] decodedBytes = BaseEncoding.base64().decode(encodedText);  
        String decodedText = new String(decodedBytes, Charsets.UTF_8);  
        // 打印结果:编码后的文本和解码后的文本应该与原始文本匹配  
        System.out.println("Original text: " + originalText);  
        System.out.println("Encoded text: " + encodedText);  
        System.out.println("Decoded text: " + decodedText);  
  
        // Throwables 示例:获取异常的根因  
        try {  
            throw new RuntimeException("Outer exception", new IOException("Inner exception"));  
        } catch (Exception e) {  
            Throwable rootCause = Throwables.getRootCause(e);  
            // 打印结果:Inner exception  
            System.out.println("Root cause: " + rootCause.getMessage());  
        }  
  
        // HashCode 示例:计算哈希值  
        String textToHash = "This is some text to hash";  
        HashCode hashCode = Hashing.sha256().hashString(textToHash, Charsets.UTF_8);  
        // 打印结果:SHA-256 哈希值  
        System.out.println("SHA-256 hash: " + hashCode);  
    }  
}

请注意以下几点:

  • Stopwatch 用于测量代码段的执行时间。
  • ClassPath 用于遍历类加载器加载的所有类资源。由于这可能会加载大量的类,因此在实际应用中要谨慎使用,避免性能问题。
  • BaseEncoding 提供了一种便捷的方式来进行 Base64 等编码方式的编码和解码操作。
  • Throwables 提供了一些实用方法来处理异常,例如获取根因。
  • HashCode 是 Guava 中表示哈希值的类,它与 java.util.Objects.hash() 不同,主要用于计算特定哈希算法(如 SHA-256)的哈希值。
  • ninterruptibles.sleepUninterruptibly() 是为了演示目的而使用的,它在实际应用中可能不是一个好的选择,因为它会无条件地忽略中断。在生产代码中,你应该更仔细地处理中断。
相关文章
|
11月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1097 29
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
12月前
|
人工智能 文字识别 自然语言处理
保单AI识别技术及代码示例解析
车险保单包含基础信息、车辆信息、人员信息、保险条款及特别约定等关键内容。AI识别技术通过OCR、文档结构化解析和数据校验,实现对保单信息的精准提取。然而,版式多样性、信息复杂性、图像质量和法律术语解析是主要挑战。Python代码示例展示了如何使用PaddleOCR进行保单信息抽取,并提出了定制化训练、版式分析等优化方向。典型应用场景包括智能录入、快速核保、理赔自动化等。未来将向多模态融合、自适应学习和跨区域兼容性发展。
|
JSON 缓存 API
解析电商商品详情API接口系列,json数据示例参考
电商商品详情API接口是电商平台的重要组成部分,提供了商品的详细信息,支持用户进行商品浏览和购买决策。通过合理的API设计和优化,可以提升系统性能和用户体验。希望本文的解析和示例能够为开发者提供参考,帮助构建高效、可靠的电商系统。
507 12
|
安全 编译器 Linux
深入解析与防范:基于缓冲区溢出的FTP服务器攻击及调用计算器示例
本文深入解析了利用缓冲区溢出漏洞对FTP服务器进行远程攻击的技术,通过分析FreeFlow FTP 1.75版本的漏洞,展示了如何通过构造过长的用户名触发缓冲区溢出并调用计算器(`calc.exe`)。文章详细介绍了攻击原理、关键代码组件及其实现步骤,并提出了有效的防范措施,如输入验证、编译器保护和安全编程语言的选择,以保障系统的安全性。环境搭建基于Windows XP SP3和Kali Linux,使用Metasploit Framework进行攻击演示。请注意,此内容仅用于教育和研究目的。
465 4
|
存储 搜索推荐 数据库
运用LangChain赋能企业规章制度制定:深入解析Retrieval-Augmented Generation(RAG)技术如何革新内部管理文件起草流程,实现高效合规与个性化定制的完美结合——实战指南与代码示例全面呈现
【10月更文挑战第3天】构建公司规章制度时,需融合业务实际与管理理论,制定合规且促发展的规则体系。尤其在数字化转型背景下,利用LangChain框架中的RAG技术,可提升规章制定效率与质量。通过Chroma向量数据库存储规章制度文本,并使用OpenAI Embeddings处理文本向量化,将现有文档转换后插入数据库。基于此,构建RAG生成器,根据输入问题检索信息并生成规章制度草案,加快更新速度并确保内容准确,灵活应对法律与业务变化,提高管理效率。此方法结合了先进的人工智能技术,展现了未来规章制度制定的新方向。
671 3
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
937 1
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
2145 1
|
前端开发 JavaScript UED
axios取消请求CancelToken的原理解析及用法示例
axios取消请求CancelToken的原理解析及用法示例
1143 0
|
JSON 前端开发 API
【淘系】商品详情属性解析(属性规格详情图sku等json数据示例返回参考),淘系API接口系列
在淘宝(或天猫)平台上,商品详情属性(如属性规格、详情图、SKU等)是商家在发布商品时设置的,用于描述商品的详细信息和不同规格选项。这些信息对于消费者了解商品特性、进行购买决策至关重要。然而,直接通过前端页面获取这些信息的结构化数据(如JSON格式)并非直接暴露给普通用户或开发者,因为这涉及到平台的商业机密和数据安全。 不过,淘宝平台提供了丰富的API接口(如淘宝开放平台API),允许有资质的开发者或合作伙伴通过编程方式获取商品信息。这些API接口通常需要注册开发者账号、申请应用密钥(App Key)和秘钥(App Secret),并遵守淘宝的API使用协议。

推荐镜像

更多