大家好,这里是 一口八宝周 👏
欢迎来到我的博客 ❤️一起交流学习
文章中有需要改进的地方请大佬们多多指点 谢谢 🙏
在本篇文章中,我将用实例展示,如何使用Joiner将集合转换为 String ,以及使用Splitter将 String 拆分为集合。
首先我们需要导入关键的依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
下面就直接代码展示
以下参考:https://www.baeldung.com/guava-joiner-and-splitter-tutorial
package guava;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.junit.Test;
import java.util.*;
public class GuavaDemo {
/**
* 1.使用Joiner将列表转换为字符串
*/
@Test
public void ListConvertString() {
List<String> names = Lists.newArrayList("zxt","lan","hhh");
String result = Joiner.on(",").join(names);
System.out.println(result); //zxt,lan,hhh
//使用Joiner处理空值,跳过空值,使用skipNulls()
List<String> nameList = Lists.newArrayList("zxt", null, "lan");
String str = Joiner.on(",").skipNulls().join(nameList);
System.out.println(str); //zxt,lan
//替换空值,使用useForNull()
String str1 = Joiner.on(",").useForNull("hhh").join(nameList);
System.out.println(str1); //zxt,hhh,lan
}
/**
* 2.使用Joiner将Map转换为字符串
*/
@Test
public void MapConvertString() {
List<String> names = Lists.newArrayList("zxt","lan","hhh");
Map<Integer,String> userMap = Maps.newHashMap();
userMap.put(1,"zxt");
userMap.put(2,"lan");
String result = Joiner.on(",").withKeyValueSeparator(":").join(userMap);
System.out.println(result); //1:zxt,2:lan
}
/**
* 3.嵌套集合,将每个List转换为String
*/
@Test
public void CollectionsJoined() {
List<ArrayList<String>> userList = Lists.newArrayList(
Lists.newArrayList("zxt","lan","hhh"),
Lists.newArrayList("java","spark","c++"),
Lists.newArrayList("hangzhou","wuhan","shanghai")
);
System.out.println(userList); //[[zxt, lan, hhh], [java, spark, c++], [hangzhou, wuhan, shanghai]]
String result = Joiner.on(";").join(Iterables.transform(userList,
new Function<ArrayList<String>, String>() {
@Override
public String apply(ArrayList<String> strings) {
return Joiner.on("-").join(strings);
}
}
));
System.out.println(result); //zxt-lan-hhh;java-spark-c++;hangzhou-wuhan-shanghai
}
/**
* 4.连接多个字符串
*/
@Test
public void CreateStrFromStr() {
//也可单独写一个方法,参数为String...args
String result = Joiner.on(",").skipNulls().join("hello", null, "lan");
System.out.println(result); //hello,lan
}
/**
* 5.使用拆分器从字符串创建list
*/
@Test
public void CreateListFromStr() {
String str = "zxt-lan-happy";
List<String> list = Splitter.on("-").trimResults().splitToList(str);
System.out.println(list); //[zxt, lan, happy]
}
/**
* 6.使用Splitter从字符串创建map
*/
@Test
public void CreateMapFromStr() {
String str = "zxt-hangzhou;lan-wuhan";
Map<String,String> userMap = Splitter.on(";").withKeyValueSeparator("-").split(str);
System.out.println(userMap); //{zxt=hangzhou, lan=wuhan}
}
/**
* 7.使用多个分隔符拆分字符串
*/
@Test
public void SplitStrOnMultipleSeparator() {
String str = "zxt.hangzhou,,lan-wuhan";
List<String> list = Splitter.onPattern("[.,-]").omitEmptyStrings().splitToList(str);
System.out.println(list); //[zxt, hangzhou, lan, wuhan]
}
/**
* 8.以特定长度拆分字符串
*/
@Test
public void SplitStrOnSpecificLength() {
String str = "zxt lan";
List<String> list = Splitter.fixedLength(2).splitToList(str);
System.out.println(JSON.toJSONString(list)); //["zx","t ","la","n"]
}
/**
* 9.限制拆分结果
*/
@Test
public void LimitSplit() {
String str = "zxt,lan,hhh,qqq,lpp";
List<String> list = Splitter.on(",").limit(3).splitToList(str);
System.out.println(JSON.toJSONString(list)); //["zxt","lan","hhh,qqq,lpp"]
}
}
通过上述代码实例,相信很多小伙伴都已经掌握了Joiner的用法,当然啦~知其然知其所以然,我们继续挖掘,看一下源码。
通过查看源码,我们可以知道
一个用分隔符连接文本片段(指定为 array, Iterable, varargs or even a Map)的对象,它要么将结果附加到Appendable,要么将其作为字符串返回。
List<String> nameList = Lists.newArrayList("zxt", null, "lan");
String str = Joiner.on(",").skipNulls().join(nameList);
以上代码为例,在返回zxt,lan结果之前,所有的元素都使用了Object.toString()转化为字符串,如果没有skipNulls()或useForNull(String)方法的话,该代码会返回NullPointerException异常。
通过代码可以看到Joiner的源码是私有的,因此不能直接去创建对象,而是通过现有提供的公有静态方法on(String separator)和on(char separator)来构建对象。
继续以上述代码为例,我们进入join方法,继而进入StringBuilder appendTo(StringBuilder builder, Iterator<?> parts)方法,该方法传入的是StringBuilder对象,为的是保证线程安全。然后调用了appendTo(A appendable, Iterator<?> parts) throws IOException方法,通过观察可以看到所有的拼接字符串最终都会调用此方法,因此该方法是Joiner的核心方法。
方法执行步骤:
由于无法保证appendable不为空即传入的builder,因此对builder进行了判空操作,如果为空的话就抛出异常。
迭代器遍历确保没有多余的分隔符。
重写了toString方法,防止容器中有null对象。
通过以上步骤完成了数据的拼接返回字符串。
好啦,就到这里~拜拜👋