为什么我们已经有StringBuilder的StringJoiner?

Hit*_*arg 56 java string stringbuilder java-8

我最近遇到了一个Java 8类StringJoiner,它使用分隔符添加了String并添加了前缀和后缀,但我无法理解这个类的需要,因为它也在StringBuilder后端使用,并且还执行非常简单的附加操作字符串.

我是否因为没有真正理解这门课的真正目的而错过了一些东西?

Mar*_*ler 65

StringJoiner当你需要加入一个字符串时,非常有用Stream.

例如,如果您必须遵循字符串列表:

final List<String> strings = Arrays.asList("Foo", "Bar", "Baz");
Run Code Online (Sandbox Code Playgroud)

它使用起来要简单得多

final String collectJoin = strings.stream().collect(Collectors.joining(", "));
Run Code Online (Sandbox Code Playgroud)

就像它会StringBuilder:

final String collectBuilder =
    strings.stream().collect(Collector.of(StringBuilder::new,
        (stringBuilder, str) -> stringBuilder.append(str).append(", "),
        StringBuilder::append,
        StringBuilder::toString));
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这两个例子是不一样的!第一个生成字符串"foo,Bar,Baz",第二个生成`"foo,Bar,Baz". (8认同)
  • `String.join(",",strings)`是`strings.stream().collect(Collectors.joining(","))的快速版本. (4认同)
  • @PaulWagland是的,这是`.joining`的额外美感.通常,你*不需要最后一个逗号...... (3认同)
  • @Koshinae完全同意,在流媒体案例中也证明了这个已经很复杂的声明更加复杂! (2认同)

Pet*_*rey 23

StringJoiner Javadoc上的示例非常擅长覆盖它.整个要点是从添加条目的行为中抽象出分离器的选择.例如,您可以创建一个木匠,指定要使用的分隔符并将其传递给库以添加元素,反之亦然.

字符串"[George:Sally:Fred]"可以构造如下:

StringJoiner sj = new StringJoiner(":", "[", "]");
sj.add("George").add("Sally").add("Fred");
String desiredString = sj.toString();
Run Code Online (Sandbox Code Playgroud)

可以使用StringJoiner来使用Collectors.joining(CharSequence)从Stream创建格式化输出.例如:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
    .map(i -> i.toString())
    .collect(Collectors.joining(", "));
Run Code Online (Sandbox Code Playgroud)

  • @Simeon如果我想在我追加的每个东西和一个字符串构建器之间需要一个隐式分隔符,我会使用String joiner.这不是关于性能,而是使所需的行动更清晰. (4认同)
  • Peter,您是否对StringBuilder与StringJoiner的性能进行了任何基准测试?从这方面你更喜欢哪一个? (2认同)

sp0*_*00m 14

在某些用例中,它可能会简化您的代码:

List<String> list = // ...;

// with StringBuilder
StringBuilder builder = new StringBuilder();
builder.append("[");
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.append("]");

// with StringJoiner
StringJoiner joiner = new StringJoiner(",", "[", "]");
for (String element : list) {
    joiner.add(element);
}
Run Code Online (Sandbox Code Playgroud)


Kon*_*kov 11

StringJoiner虽然它没有实现接口,但它是一种收集器Collector.它只是表现得这样.除了可以传递分隔符,前缀和后缀之外,StringJoiner还可以使用它来从Stream调用创建格式化输出Collectors.joining(CharSequence).

这在使用并行流时尤其有用,因为在某些时候,并行处理的批处理需要连接,这就是StringJoiner发生的地方.

  • 不完全是.它是一个适合在收集器中使用的低级实用程序组件(join()确实使用它),但也适用于Streams世界之外.人们总是写这种循环. (7认同)

Shu*_*dey 5

StringJoiner 比使用 StringBuilder 简单得多。一个非常简单的代码就像

StringJoiner sj = new StringJoiner(",");
        sj.add("aaa");
        sj.add("bbb");
        sj.add("ccc");
        String result = sj.toString(); //aaa,bbb,ccc
Run Code Online (Sandbox Code Playgroud)