本文主要介绍Guava中几种处理字符串和Map的方法,包括Joiner(连接)、FluentIterable(过滤、转换集合)和Splitter(分割)。本文基于Java 8进行测试,Guava 版本为:

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

Joiner

我们来看看下面经常遇见的一个案例:定义包含如下元素的一个列表,请按照英文逗号分割,并过滤掉值为null的元素。

"a", null, "b", "g", "8", "9"

用JDK中的方法做的实现方案如下:

    @Test
public void joinerListByJdkTest() {
List<String> lists = Lists.newArrayList("a", null, "b", "g", "8", "9");
StringBuilder sb = new StringBuilder();
for (Object item : lists) {
if (item != null) {
sb.append(item)
.append(DELIMITER);
}
}
LOGGER.info(sb.substring(0, sb.length() - DELIMITER.length()));
}

执行结果:a,b,g,8,9。

是不是很简单,但是繁琐?例如,在for循环执行结束之后必须修正字符串末尾的分隔符:sb.substring(0, sb.length() - DELIMITER.length());Guava版本呢?

    @Test
public void joinerListByGuavaTest() {
List<String> lists = Lists.newArrayList("a", null, "b", "g", "8", "9");
String result = Joiner.on(DELIMITER).skipNulls().join(lists);
LOGGER.info(result);
}

我们不再考虑更多的细节,并且很有语义的告诉代码的阅读者用什么分隔符分隔,需要过滤null值再join。

关于Map对象的连接,Guava提供了withKeyValueSeparator用于指定键值对直接的分隔符。

    /**
* joiner withKeyValueSeparator(String keyValueSeparator) map连接器,keyValueSeparator为key和value之间的分隔符
* <p>
* 结果:
* 1:哈哈,2:压压
*/
@Test
public void withMapTest() {
Map<Integer, String> maps = Maps.newHashMap();
maps.put(1, "哈哈");
maps.put(2, "压压");
String result = Joiner.on(DELIMITER).withKeyValueSeparator(":").join(maps);
System.out.println(result);
}

FluentIterable

转换(transform)集合类型,transform接收Function接口,一般在方法中采用new接口实现回调方法apply的方式。

FluentIterable 是guava集合类中常用的一个类,主要用于过滤、转换集合中的数据;它是一个抽象类,实现了Iterable接口,大多数方法都返回FluentIterable对象,这也是guava的思想之一。下面主要针对filter 和transform方法进行演示。filter方法要接收Predicate接口,transform接收Function接口。

Filter的应用实例:

    /**
* 过滤出年龄大于20岁的学生
* <p>
* 这里有一个潜在的坑,在高版本(21.0++)的guava中Predicate接口继承了java 8中的java.util.function.Predicate
*
* @param students
*/
public static void filterStudents(List<Student> students) {
FluentIterable<Student> filter = FluentIterable.from(students).filter(
new Predicate<Student>() {
@Override
public boolean apply(Student student) {
return Integer.valueOf(student.getAge()) > 20;
}
});
for (Student student : filter) {
System.out.println(student);
}
}

transform三种类型的应用:

    private void myTest(List<Student> students) {
FluentIterable<String> transform = (FluentIterable<String>) FluentIterable.from(students).transform(
new Function<Student, String>() {
@Override
public String apply(Student user) {
// 以分隔符#分隔姓名和年龄
return Joiner.on("#").join(user.getName(), user.getAge());
}
});
for (String user : transform) {
System.out.println(user);
}
} /**
* 返回格式化后的列表
*/
private void myTestList(List<Student> students) {
// 直接返回 List 类型对象
List<String> transform = FluentIterable.from(students).transform(
new Function<Student, String>() {
@Override
public String apply(Student user) {
return Joiner.on("=").join(user.getName(), user.getAge());
}
}).toList();
System.out.println(transform);
} /**
* 定制特殊格式,并返回合并后的字符串
* 这里有一个潜在的坑,在版本 18.0才可以使用 .join(Joiner.on("、"))
* @param students
*/
private void givenFormater(List<Student> students) {
String result = FluentIterable.from(students).transform(new Function<Student, String>() {
@Override
public String apply(Student user) {
// 通过特殊格式定制字符串
return user.getName() + "(" + user.getAge() + ")";
}
// 指定各个字符串之间的分隔符
}).join(Joiner.on("、")); System.out.println(result);
}
@Test
public void guavaStudy() {
List<Student> students = new ArrayList<>();
Student student = new Student();
student.setName("Lucy");
student.setAge("19");
students.add(student);
students.add(new Student("Wiener", "32", "河南商丘"));
students.add(new Student("East7", "21")); myTest(students);
LOGGER.info("----- givenFormater ------");
givenFormater(students);
myTestList(students);
LOGGER.info("----- filterStudents ------");
filterStudents(students);
}

函数givenFormater比较特殊,其执行结果如下:

Lucy(19)、Wiener(32)、East7(21)

可以看到,其定制结果集格式的功能非常强悍。

Splitter

Splitter可以对字符串进行分割,其分割的方式有两种——按字符/字符串分割和按正则进行分割,下面分析按字符分隔。

   /**
* on 按照指定分隔符分隔字符串
* 结果:[ 河南商丘, 767, 32, , 哈哈 ]
*/
@Test
public void splitterListTest() {
String test = " 河南商丘,767,32,,哈哈 ";
List<String> lists = Splitter.on(DELIMITER).splitToList(test);
System.out.println(lists);
}
/**
* trimResults 拆分并且去除元素前后空格
* <p>
* 结果:[河南商丘, 767, 32, , 哈哈]
*/
@Test
public void trimResultListTest() {
String test = " 河南商丘,767,32,,哈哈 ";
List<String> lists = Splitter.on(DELIMITER).trimResults().splitToList(test);
System.out.println(lists);
} /**
* omitEmptyStrings 去除拆分后的、空的字符串
* <p>
* 结果:[河南商丘, 767, 32, 哈哈]
*/
@Test
public void omitEmptyStringsTest() {
String test = " 河南商丘,767,32,,哈哈 ";
List<String> lists = Splitter.on(DELIMITER).omitEmptyStrings().trimResults().splitToList(test);
System.out.println(lists);
}

Reference

https://www.cnblogs.com/whitewolf/p/4214749.html

<

Guava中的常见集合操作用法的更多相关文章

  1. JavaScript常见集合操作

    JavaScript常见集合操作 集合的遍历 FOR循环(效率最高) 优点:JavaScript最普遍的for循环,执行效率最高 缺点:无法遍历对象 for(let i=0;i<array.le ...

  2. 强大的Guava中的新集合类型: Multiset, Multimap, BiMap, Table, ClassToInstanceMap, RangeSet, RangeMap等

    一 Multiset /** * 新类型集合: Multiset: Multiset就是可以保存多个相同的对象,并且无序 * 占据了List和Set之间的一个灰色地带 * 其他实现: TreeMult ...

  3. Python中的SET集合操作

    python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和 ...

  4. 认识python中的set集合及其用法

    python中,集合(set)是一个无序排列,可哈希, 支持集合关系测试,不支持索引和切片操作,没有特定语法格式, 只能通过工厂函数创建.集合里不会出现两个相同的元素, 所以集合常用来对字符串或元组或 ...

  5. Python中字典和集合的用法

    本人开始学习python 希望能够慢慢的记录下去 写下来只是为了害怕自己忘记. python中的字典和其他语言一样 也是key-value的形式  利用空间换时间 可以进行快速的查找 key 是唯一的 ...

  6. Guava中Predicate的常见用法

    Guava中Predicate的常见用法 1.  Predicate基本用法 guava提供了许多利用Functions和Predicates来操作Collections的工具,一般在 Iterabl ...

  7. Guava库介绍之集合(Collection)相关的API

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...

  8. java中的集合操作类(未完待续)

    申明: 实习生的肤浅理解,如发现有错误之处.还望大牛们多多指点 废话 事实上我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList ...

  9. Linux中find常见用法

    Linux中find常见用法示例 ·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \; find命令的参数 ...

  10. [转]Linux中find常见用法示例

    Linux中find常见用法示例[转]·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;find命令的参 ...

随机推荐

  1. manim边学边做--局部缩放的场景类

    在动画制作中,尤其是数学和科学可视化领域,有时我们需要将观众的注意力集中在场景的某个特定部分. Manim提供了一个强大的工具 ZoomedScene,它允许我们在场景中创建一个独立的缩放视图,从而实 ...

  2. SVG path 标签根据两点和角度绘制弧线

    同步发布:https://blog.jijian.link/2020-04-14/svg-arc/ 由于功能受限,此处不能放 iframe 嵌入链接,如需看到实时效果,请移步 https://blog ...

  3. 万字长文详解SIFT特征提取

    本文对 SIFT 算法进行了详细梳理.SIFT即尺度不变特征变换(Scale-Invariant Feature Transform),是一种用于检测和描述图像局部特征的算法.该算法对图像的尺度和旋转 ...

  4. 10 卷积神经网络CNN原理

    1. 全连接层 前文中我们讨论的几乎都是全连接层,也就是在层间,每个神经元都与前一层的所有神经元相连接,如图: 也就是每层的每个feature,都与前一层所有features相关联,是前一层所有fea ...

  5. TaskPyro:一个轻量级的 Python 任务调度和爬虫管理平台

    前言 推荐一款本人在使用的Python爬虫管理平台,亲测不错!!! TaskPyro 是什么? TaskPyro 是一个轻量级的 Python 任务调度平台,专注于提供简单易用的任务管理和爬虫调度解决 ...

  6. 实现领域驱动设计 - 使用ABP框架 - 系列文章汇总

    系列文章汇总 前言: 最近看到ABP官网的一本电子书,感觉写的很好,翻译出来,一起学习下 Implementing Domain Driven Design 实现领域驱动设计 - 使用ABP框架 - ...

  7. 一文速通Python并行计算:04 Python多线程编程-多线程同步(上)—基于条件变量、事件和屏障

    一文速通 Python 并行计算:04 Python 多线程编程-多线程同步(下)-基于条件变量.事件和屏障 摘要: 本文介绍了 Python 多线程同步的三种机制:条件变量(Condition).事 ...

  8. 新更新 Scanner键盘输入

    原来我们都是将写好的代码进行打印,这是硬程序,如果我们想让电脑实时输入我们想要的值,就需要使用Scanner进行键盘录入 1.让电脑找到Scanner符咒(电脑自动) 2.召唤Scanner精灵 3. ...

  9. 探秘Transformer系列之(22)--- LoRA

    探秘Transformer系列之(22)--- LoRA 目录 探秘Transformer系列之(22)--- LoRA 0x00 概述 0x01 背景知识 1.1 微调 1.2 PEFT 1.3 秩 ...

  10. Service Reliability Management: A Comprehensive Overview

    Service Reliability Management: A Comprehensive Overview Service reliability management is a critica ...