网站制作费用及后期运营/属性词 关键词 核心词
文章目录
- 你还不会使用Guava处理字符串? 那你还不进来学习?
- 连接器[Joiner]
- 拆分器[Splitter]
- 参考
- 源代码
你还不会使用Guava处理字符串? 那你还不进来学习?
连接器[Joiner]
用分隔符把字符串序列连接起来也可能会遇上不必要的麻烦。如果字符串序列中含有null,那连接操作会更难。但是连接器Joiner让我们连接字符串变得更加简单
比如我们现在一个字符串的集合,然后我们需要用‘#’来把这个集合中的数据连接起来,用Joiner怎么做呢?
public class JoinerTest {private final List<String> stringList = Arrays.asList("Google", "Guava", "Java", "Scala", "Kafka");@Testpublic void testJoinOnJoin() {String result = Joiner.on("#").join(stringList);Assertions.assertEquals("Google#Guava#Java#Scala#Kafka", result);}
}
通过Joiner.on("#").join(stringList);
就可以把一个集合通过某个连接符来连接成字符串
那如果现在我们的集合中包含null
,该如何处理,正常我们写程序可能会没考虑到这种空指针的问题。
public class JoinerTest {private final List<String> stringListWithNullValue = Arrays.asList("Google", "Guava", "Java", "Scala", null);@Testpublic void testJoinOnJoinWithNullValue() {assertThrows(NullPointerException.class, () -> {String result = Joiner.on("#").join(stringListWithNullValue);});}
}
比如如果用Joiner.on("#").join(stringListWithNullValue)
,对于集合中有null
的情况是会报空指针异常的,那种情况我们要怎么处理?
我们可以通过skipNulls()
来过滤掉集合中的null
元素。
public class JoinerTest {private final List<String> stringListWithNullValue = Arrays.asList("Google", "Guava", "Java", "Scala", null);@Testpublic void testJoinOnJoinWithNullValueButSkip() {String result = Joiner.on("#").skipNulls().join(stringListWithNullValue);Assertions.assertEquals("Google#Guava#Java#Scala", result);}}
而且通过这种Fluent风格的Joiner让连接字符串更简单。
那再比如说,我们有个要求是当集合元素有null
元素的时候,我们需要用默认值去代替,该怎么做呢?
package org.example.joiner;import com.google.common.base.Joiner;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.util.Arrays;
import java.util.List;import static org.junit.jupiter.api.Assertions.assertThrows;public class JoinerTest {private final List<String> stringListWithNullValue = Arrays.asList("Google", "Guava", "Java", "Scala", null);@Testpublic void testJoin_On_Join_WithNullValue_UseDefaultValue() {String result = Joiner.on("#").useForNull("DEFAULT").join(stringListWithNullValue);Assertions.assertEquals("Google#Guava#Java#Scala#DEFAULT", result);}
}
我们可以使用useForNull("默认代替的字符串")
来完成连接。
public class Joiner {public static Joiner on(String separator) {return new Joiner(separator);}public static Joiner on(char separator) {return new Joiner(String.valueOf(separator));}}
Joiner的on
方法总会返回一个新的joiner实例。这使得joiner实例都是线程安全的
使用的方式还有很多,还可以把集合连接后返回一个StringBuilder
对象
@Testpublic void testJoin_On_Append_To_StringBuilder() {final StringBuilder builder = new StringBuilder();StringBuilder resultBuilder = Joiner.on("#").useForNull("DEFAULT").appendTo(builder, stringListWithNullValue);assertSame(resultBuilder,builder);//传入的对象和返回出来的对象是同一个对象assertEquals("Google#Guava#Java#Scala#DEFAULT",resultBuilder.toString());assertEquals("Google#Guava#Java#Scala#DEFAULT",builder.toString());}
当然还可以把集合连接后写入一个文件流中
@Testpublic void testJoin_On_Append_To_Writer() {final String targetFileName = "guava-joiner.txt";try (FileWriter writer = new FileWriter(new File(targetFileName))) {Joiner.on("#").useForNull("DEFAULT").appendTo(writer, stringListWithNullValue);assertTrue(Files.isFile().test(new File(targetFileName)));} catch (IOException e) {fail("append to the writer occur fetal error.");}}
题外话题,现在我们考虑一下,如果不用Guava的Joiner我们平时该怎么处理这种字符串的连接呢?其实利用java8也是可以很快实现的,只是没有Guava这么简单便捷。
public class JoinerTest {private final List<String> stringListWithNullValue = Arrays.asList("Google", "Guava", "Java", "Scala", null);@Testpublic void testJoiningByStreamWithDefaultValue() {String result = stringListWithNullValue.stream().map(this::defaultValue).collect(joining("#"));assertEquals("Google#Guava#Java#Scala#DEFAULT", result);}private String defaultValue(final String item) {return item == null || item.isEmpty() ? "DEFAULT" : item;}
}
还有对于map这种key,value形式,Guava的Joiner可以用withKeyValueSeparator
方法进行连接。
@Testpublic void testJoinOnWithMap() {final Map<String, String> stringMap = of("Hello", "Guava", "Java", "Scala");assertEquals("Hello=Guava#Java=Scala", Joiner.on('#').withKeyValueSeparator("=").join(stringMap));}
拆分器[Splitter]
JDK内建的字符串拆分工具有一些古怪的特性。比如,String.split悄悄丢弃了尾部的分隔符。 问题:
”,a, ,b,”.split(“,”)
返回什么呢?
package org.example.splitter;import org.junit.jupiter.api.Test;import java.util.Arrays;import static org.junit.jupiter.api.Assertions.assertEquals;public class SplitterTest {@Testpublic void test_string_split() {String str = ",a, ,b,";String[] split = str.split(",");assertEquals(4, split.length);assertEquals("[, a, , b]", Arrays.toString(split));}}
所以这不是我们期望的结果,我们期望的结果只是需要拿到a和b两个字符,那如果通过Guava的Splitter,我们就可以很容易的做到。
@Testpublic void testSplitOnSplit() {List<String> result = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(",a, ,b,");assertEquals(2,result.size());assertEquals("a",result.get(0));assertEquals("b",result.get(1));}
看到了吧,这就是Splitter的厉害之处。再继续看多几个例子
@Testpublic void testSplit_On_Split_OmitEmpty() {List<String> result = Splitter.on("|").splitToList("hello|world|||");assertNotNull(result);assertEquals(5, result.size());//过滤掉split之后的空字符串result = Splitter.on("|").omitEmptyStrings().splitToList("hello|world|||");assertNotNull(result);assertEquals(2, result.size());}@Testpublic void testSplit_On_Split_OmitEmpty_TrimResult() {List<String> result = Splitter.on("|").omitEmptyStrings().splitToList("hello | world|||");assertNotNull(result);assertEquals(2, result.size());assertEquals("hello ", result.get(0));assertEquals(" world", result.get(1));//过滤掉split之后的空字符串并把结果进行trim操作result = Splitter.on("|").trimResults().omitEmptyStrings().splitToList("hello | world|||");assertEquals("hello", result.get(0));assertEquals("world", result.get(1));}@Testpublic void testSplitFixLength() {//还可以按照长度进行分割List<String> result = Splitter.fixedLength(4).splitToList("aaaabbbbccccdddd");assertNotNull(result);assertEquals(4, result.size());assertEquals("aaaa", result.get(0));assertEquals("bbbb", result.get(1));assertEquals("cccc", result.get(2));assertEquals("dddd", result.get(3));}@Testpublic void testSplitOnSplitLimit() {//限制分割后的结果集个数List<String> result = Splitter.on("#").limit(3).splitToList("hello#world#java#google#scala");assertNotNull(result);assertEquals(3, result.size());assertEquals("hello", result.get(0));assertEquals("world", result.get(1));assertEquals("java#google#scala", result.get(2));}@Testpublic void testSplitOnSplitLimit() {//限制分割后的结果集个数List<String> result = Splitter.on("#").limit(3).splitToList("hello#world#java#google#scala");assertNotNull(result);assertEquals(3, result.size());assertEquals("hello", result.get(0));assertEquals("world", result.get(1));assertEquals("java#google#scala", result.get(2));}@Testpublic void testSplitOnPatternString() {//还可以按照正则表达式分割List<String> result = Splitter.onPattern("\\|").trimResults().omitEmptyStrings().splitToList("hello | world|||");assertNotNull(result);assertEquals(2,result.size());assertEquals("hello",result.get(0));assertEquals("world",result.get(1));}@Testpublic void testSplitOnPattern() {List<String> result = Splitter.on(Pattern.compile("\\|")).trimResults().omitEmptyStrings().splitToList("hello | world|||");assertNotNull(result);assertEquals(2,result.size());assertEquals("hello",result.get(0));assertEquals("world",result.get(1));}@Testpublic void testSplitOnSplitToMap() {Map<String, String> result = Splitter.on(Pattern.compile("\\|")).trimResults().omitEmptyStrings().withKeyValueSeparator("=").split("hello=HELLO| world=WORLD|||");assertNotNull(result);assertEquals(2,result.size());assertEquals("HELLO",result.get("hello"));assertEquals("WORLD",result.get("world"));}
怎么样?你学废了吗?
参考
[Google Guava] 6-字符串处理:分割,连接,填充
guava常用工具总结
Google guava工具类的介绍和使用
源代码
https://gitee.com/cckevincyh/guava-demo