欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 8中字符串拼接新姿势StringJoiner详解

程序员文章站 2022-07-01 17:03:20
在为什么阿里巴巴不建议在for循环中使用”+”进行字符串拼接一文中,我们介绍了几种java中字符串拼接的方式,以及优缺点。其中还有一个重要的拼接方式我没有介绍,那就是jav...

在为什么阿里巴巴不建议在for循环中使用”+”进行字符串拼接一文中,我们介绍了几种java中字符串拼接的方式,以及优缺点。其中还有一个重要的拼接方式我没有介绍,那就是java 8中提供的stringjoiner ,本文就来介绍一下这个字符串拼接的新兵。

如果你想知道一共有多少种方法可以进行字符串拼接,教你一个简单的办法,在intellij idea中,定义一个java bean,然后尝试使用快捷键自动生成一个tostring方法,idea会提示多种tostring生成策略可供选择。

11111

目前我使用的idea的tostring生成策略默认的是使用jdk 1.8提供的stringjoiner。

介绍

stringjoiner是java.util包中的一个类,用于构造一个由分隔符分隔的字符序列(可选),并且可以从提供的前缀开始并以提供的后缀结尾。虽然这也可以在stringbuilder类的帮助下在每个字符串之后附加分隔符,但stringjoiner提供了简单的方法来实现,而无需编写大量代码。

stringjoiner类共有2个构造函数,5个公有方法。其中最常用的方法就是add方法和tostring方法,类似于stringbuilder中的append方法和tostring方法。

用法

stringjoiner的用法比较简单,下面的代码中,我们使用stringjoiner进行了字符串拼接。

public class stringjoinertest {

  public static void main(string[] args) {
    stringjoiner sj = new stringjoiner("hollis");

    sj.add("hollischuang");
    sj.add("java干货");
    system.out.println(sj.tostring());

    stringjoiner sj1 = new stringjoiner(":","[","]");

    sj1.add("hollis").add("hollischuang").add("java干货");
    system.out.println(sj1.tostring());
  }
}

以上代码输出结果:

hollischuanghollisjava干货
[hollis:hollischuang:java干货]

值得注意的是,当我们stringjoiner(charsequence delimiter)初始化一个stringjoiner的时候,这个delimiter其实是分隔符,并不是可变字符串的初始值。

stringjoiner(charsequence delimiter,charsequence prefix,charsequence suffix)的第二个和第三个参数分别是拼接后的字符串的前缀和后缀。

原理

介绍了简单的用法之后,我们再来看看这个stringjoiner的原理,看看他到底是如何实现的。主要看一下add方法:

public stringjoiner add(charsequence newelement) {
  preparebuilder().append(newelement);
  return this;
}

private stringbuilder preparebuilder() {
  if (value != null) {
    value.append(delimiter);
  } else {
    value = new stringbuilder().append(prefix);
  }
  return value;
}

看到了一个熟悉的身影——stringbuilder ,没错,stringjoiner其实就是依赖stringbuilder实现的,在为什么阿里巴巴不建议在for循环中使用”+”进行字符串拼接中我们介绍过stringbuilder的实现原理,本文不在赘述。

当我们发现stringjoiner其实是通过stringbuilder实现之后,我们大概就可以猜到,他的性能损耗应该和直接使用stringbuilder差不多!

为什么需要stringjoiner

在了解了stringjoiner的用法和原理后,可能很多读者就会产生一个疑问,明明已经有一个stringbuilder了,为什么java 8中还要定义一个stringjoiner呢?到底有什么好处呢?

如果读者足够了解java 8的话,或许可以猜出个大概,这肯定和stream有关。

作者也在java doc中找到了答案:

a stringjoiner may be employed to create formatted output from a stream using collectors.joining(charsequence)

试想,在java中,如果我们有这样一个list:

list<string> list = immutablelist.of("hollis","hollischuang","java干货");

如果我们想要把他拼接成一个以下形式的字符串:

hollis,hollischuang,java干货

可以通过以下方式:

stringbuilder builder = new stringbuilder();

if (!list.isempty()) {
  builder.append(list.get(0));
  for (int i = 1, n = list.size(); i < n; i++) {
    builder.append(",").append(list.get(i));
  }
}
builder.tostring();

还可以使用:

list.stream().reduce(new stringbuilder(), (sb, s) -> sb.append(s).append(','), stringbuilder::append).tostring();

但是输出结果稍有些不同,需要进行二次处理:

hollis,hollischuang,java干货,

还可以使用”+”进行拼接:

list.stream().reduce((a,b)->a + "," + b).tostring();

以上几种方式,要么是代码复杂,要么是性能不高,或者无法直接得到想要的结果。

为了满足类似这样的需求,java 8中提供的stringjoiner就派上用场了。以上需求只需要一行代码:

list.stream().collect(collectors.joining(":"))

即可。上面用的表达式中,collectors.joining的源代码如下:

public static collector<charsequence, ?, string> joining(charsequence delimiter,
                             charsequence prefix,
                             charsequence suffix) {
  return new collectorimpl<>(
      () -> new stringjoiner(delimiter, prefix, suffix),
      stringjoiner::add, stringjoiner::merge,
      stringjoiner::tostring, ch_noid);
}

其实现原理就是借助了stringjoiner。

当然,或许在collector中直接使用stringbuilder似乎也可以实现类似的功能,只不过稍微麻烦一些。所以,java 8中提供了stringjoiner来丰富stream的用法。

而且stringjoiner也可以方便的增加前缀和后缀,比如我们希望得到的字符串是[hollis,hollischuang,java干货]而不是hollis,hollischuang,java干货的话,stringjoiner的优势就更加明显了。

总结

本文介绍了java 8中提供的可变字符串类——stringjoiner,可以用于字符串拼接。

stringjoiner其实是通过stringbuilder实现的,所以他的性能和stringbuilder差不多,他也是非线程安全的。

如果日常开发中中,需要进行字符串拼接,如何选择?

1、如果只是简单的字符串拼接,考虑直接使用”+”即可。

2、如果是在for循环中进行字符串拼接,考虑使用stringbuilder和stringbuffer。

3、如果是通过一个list进行字符串拼接,则考虑使用stringjoiner。

以上就是本次介绍的全部知识点内容,感谢大家对的支持。