普通人怎么样做网站,设计公司灰白色调网站,wordpress 5编辑器使用,网站建设补充报价单Guava 中有一些基础的工具类#xff0c;如下所列#xff1a;
1#xff0c;Joiner 类#xff1a;根据给定的分隔符把字符串连接到一起。MapJoiner 执行相同的操作#xff0c;但是针对 Map 的 key 和 value。
2#xff0c;Splitter 类#xff1a;与 Joiner 操作相反的类…Guava 中有一些基础的工具类如下所列
1Joiner 类根据给定的分隔符把字符串连接到一起。MapJoiner 执行相同的操作但是针对 Map 的 key 和 value。
2Splitter 类与 Joiner 操作相反的类是根据给定的分隔符把一个字符串分隔成若个子字符串。
3CharMatcherStrings 类对字符串通用的操作例如移除字符串的某一部分字符串匹配等等操作。
4其他类针对Object操作的方法例如 toString 和 hashCode 方法等。
Joiner是guava.jar包下的一个类,将数组集合map等类型用指定的字符进行分割。
Joiner的用法
!-- https://mvnrepository.com/artifact/com.google.guava/guava --
dependencygroupIdcom.google.guava/groupIdartifactIdguava/artifactIdversion23.0/version
/dependency1.对数组进行分割-----join
Test
public void testStringJoin() {String str[] { aaa, vbbb, ccc, ddd };String ss Joiner.on().join(str);System.out.println(ss);//aaavbbbcccddd
}2.对List进行分割替换集合中的Null值—useForNull
Test
public void testUseForNull() {ListInteger list Arrays.asList(1, 2, 3, 4, 5, null, 6);String str Joiner.on(;).useForNull(*).join(list);System.out.println(str);//1;2;3;4;5;*;6
}3.对List进行分割消除集合中的Null值----skipNulls
Test
public void testSkipNulls() {ListInteger list Arrays.asList(1, 2, 3, 4, 5, null, 6);String str Joiner.on().skipNulls().join(list);System.out.println(str);//123456
}4.对StringBuilder或StringBuffer进行追加----appendTo
Test
public void testAppendTo() {StringBuilder stringBuilder new StringBuilder(aaa_);ListString strs Arrays.asList(bbb, ccc, ddd);StringBuilder sb Joiner.on(_).appendTo(stringBuilder, strs);System.out.println(sb.toString());//aaa_bbb_ccc_ddd
}
5.对Map进行分割-----withKeyValueSeparator
Test
public void testMapJoiner() {MapString, String map new HashMapString, String();map.put(name, 张三);map.put(age, 13);map.put(sex, M);String str Joiner.on().withKeyValueSeparator().join(map);System.out.println(str);//sexMname张三age13
}使用 Joiner 类
我们通常根据指定的分隔符来连接字符串是这样做的。 public String buildString(ListString stringList, String delimiter){StringBuilder builder new StringBuilder();for (String s : stringList) {if(s ! null){builder.append(s).append(delimiter);}}builder.setLength(builder.length() – delimiter.length());return builder.toString();
}上面的代码注意的一点就是我们要移除字符串最后的一个分隔符。虽然不难但是很无聊下面用 Joiner 类来实现同样的功能 Joiner.on(|).skipNulls().join(stringList); // 默认使用“|”作为分隔符是不是很简洁如果你想替换为 null 的字符串使用下面的方法
Joiner.on(|).useForNull(no value).join(stringList);需要注意的是Joiner 不仅可以操作字符串还可以是数组迭代器可变参数。Joiner 类是不可变类因此是线程安全的它可以处理 static final 的变量考虑到这一点我们看下面的代码 Joiner stringJoiner Joiner.on(|).skipNulls();//the useForNull() method returns a new instance of the Joiner!stringJoiner.useForNull(missing);stringJoiner.join(foo,bar,null);在上面的代码中useForNull()方法没有起作用null值还是被忽略了。
Joiner 不仅可以返回string 还有方法能够处理StringBuilder类
StringBuilder stringBuilder new StringBuilder();
Joiner joiner Joiner.on(|).skipNulls();
//returns the StringBuilder instance with the values foo,bar,baz appeneded with | delimiters
joiner.appendTo(stringBuilder,foo,bar,baz);只要是实现了 Appendble 接口的类都可以用 Joiner 来处理。
FileWriter fileWriter new FileWriter(new File(path)):
ListDate dateList getDates();
Joiner joiner Joiner.on(#).useForNulls( );
//returns the FileWriter instance with the values appended into it
joiner.appendTo(fileWriter,dateList);上面的例子中我们传递了 FileWriter 实例 和 Data 对象给 JoinerJoiner 将连接list中所有的数据给 FileWriter 实例并返回。
如上所示Joiner 是一个非常有用的类很容易处理日常的一些任务。还有一个特殊的方法它和 Joiner 的工作方式是一样但是它连接的是根据指定的分隔符连接 Map 的 key 和 value。
mapJoiner Joiner.on(#).withKeyValueSeparator();下面的单元测试类展示了如何连接 Map 的 key-value。
MapString, String testMap Maps.newLinkedHashMap();testMap.put(Washington D.C, Redskins);testMap.put(New York City, Giants);testMap.put(Philadelphia, Eagles);testMap.put(Dallas, Cowboys);String returnedString Joiner.on(#).withKeyValueSeparator().join(testMap);System.out.println(returnedString);运行结果Washington D.CRedskins#New York CityGiants#PhiladelphiaEagles#DallasCowboys
使用示例
以下参考官方文档。
开发过程中用分隔符连接字符串序列可能是一个比较繁琐的过程但本不应该如此。Joiner 可以简化这个操作。
如果序列中包含 null 值那么可以使用 Joiner 跳过 null 值 // 跳过 null 值result Joiner.on(; ).skipNulls().join(Harry, null, Ron, Hermione);Assert.assertEquals(result, Harry; Ron; Hermione);也可以通过 useForNull(String) 来将 null 值替换为指定的字符串。 // 替换 null 值result Joiner.on(; ).useForNull(null).join(Harry, null, Ron, Hermione);Assert.assertEquals(result, Harry; null; Ron; Hermione);同样可以在对象上使用 Joiner,最终会调用对象的 toString() 方法。 // 使用在对象上会调用对象的 toString() 函数result Joiner.on(,).join(Arrays.asList(1, 5, 7));Assert.assertEquals(result, 1,5,7);对于 Map ,可以使用这样的代码 // MapJoiner 的使用将 map 转换为字符串Map map ImmutableMap.of(k1, v1, k2, v2);result Joiner.on(; ).withKeyValueSeparator().join(map);Assert.assertEquals(result, k1v1; k2v2);源码分析
初始化方法
Joiner 的构造方法被设置成了私有需要通过静态的 on(String separator) 或者 on(char separator) 函数初始化。
拼接基本函数
Joiner 了中最为核心的函数就是 A appendTo(A appendable, Iterator parts)。作为全功能函数其它所有的字符串拼接最终都会调用这个函数。 public A extends Appendable A appendTo(A appendable, Iterator? parts) throws IOException {checkNotNull(appendable);if (parts.hasNext()) {appendable.append(toString(parts.next()));while (parts.hasNext()) {appendable.append(separator);appendable.append(toString(parts.next()));}}return appendable;}这段代码的分析如下
这里的 Appendable 源码中传入的是实现该接口的 StringBuilder。因为是公共方法无法保证 appendable 值不为空所以要先检查该值是否为空。if ... while ... 的结构确保末尾不会添加多余的分隔符。通过本地 toString 方法而不是直接调用对象的 toString 方法这种做法提供了空指针保护。
不可能发生的异常
在源码中有个地方的处理值得关注一下 public StringBuilder appendTo(StringBuilder builder, Iterator? extends Entry?, ? entries) {try {appendTo((Appendable) builder, entries);} catch (IOException impossible) {throw new AssertionError(impossible);}return builder;}这里之所以 IOException 的变量名取名为 impossible 是因为虽然 Appendable 接口的 append 方法会抛出 IOException但是传入的 StringBuilder 在实现的时候并不会抛出改异常所以为了适应这个接口这里不得不捕捉异常。这样捕捉后的断言处理也就可以理解了。
巧妙的可变长参数转换
有一个添加的重载函数如下所示 public final A extends Appendable A appendTo(A appendable, NullableDecl Object first, NullableDecl Object second, Object... rest)throws IOException {return appendTo(appendable, iterable(first, second, rest));}其中 iterable 函数将参数变为一个可以迭代的序列该函数如下所示。
private static IterableObject iterable(final Object first, final Object second, final Object[] rest) {checkNotNull(rest);return new AbstractListObject() {Overridepublic int size() {return rest.length 2;}Overridepublic Object get(int index) {switch (index) {case 0:return first;case 1:return second;default:return rest[index - 2];}}};}通过实现 AbstractList 的方式巧妙地复用了编译器生成的数组减少了对象创建的开销。这样的实现需要对迭代器有深入的了解因为要确保实现能够满足迭代器接口各个函数的语义。
Joiner 二次创建
因为 Joiner 创建后就是不可更改的了所以为了实现 useForNull 和 skipNulls 等语义源码会再次创建一个匿名类并覆盖相应的方法。
useForNull 函数汇中为了防止重复调用 useForNull 和 skipNulls还特意覆盖了这两个方法一旦调用就抛出运行时异常。为什么不能重复调用 useForNull 因为覆盖了 toString 方法而覆盖实现中需要调用覆盖前的 toString。 public Joiner useForNull(final String nullText) {checkNotNull(nullText);return new Joiner(this) {OverrideCharSequence toString(NullableDecl Object part) {return (part null) ? nullText : Joiner.this.toString(part);}Overridepublic Joiner useForNull(String nullText) {throw new UnsupportedOperationException(already specified useForNull);}Overridepublic Joiner skipNulls() {throw new UnsupportedOperationException(already specified useForNull);}};}skipNulls 函数实现如下所示。个人比较奇怪的是 skipNulls 中为什么不禁止重复调用 skipNulls 函数。 public Joiner skipNulls() {return new Joiner(this) {Overridepublic A extends Appendable A appendTo(A appendable, Iterator? parts) throws IOException {checkNotNull(appendable, appendable);checkNotNull(parts, parts);while (parts.hasNext()) {Object part parts.next();if (part ! null) {appendable.append(Joiner.this.toString(part));break;}}while (parts.hasNext()) {Object part parts.next();if (part ! null) {appendable.append(separator);appendable.append(Joiner.this.toString(part));}}return appendable;}Overridepublic Joiner useForNull(String nullText) {throw new UnsupportedOperationException(already specified skipNulls);}Overridepublic MapJoiner withKeyValueSeparator(String kvs) {throw new UnsupportedOperationException(cant use .skipNulls() with maps);}};}Java字符串拼接写法 joiner.on
1、 joiner.on
String result Joiner.on(,).join(list);这种写法最简单直接Joiner.on 拼接 “,” “#” “、”_ “-” 之类的
也是最常用的方法
2、 StringBuilder
StringBuilder strBur new StringBuilder();
list.forEach(val - {strBur.append(val).append(#);
});
strBur.toString();这种就是平常StringBuffer的写法一个个遍历循环的去append添加
3、Java8Stream的写法
String result list.stream().collect(Collectors.joining(_));