为什么在我们已经有StringBuilder的情况下,为什么选择StringJoiner?

2022-08-31 13:20:12

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

我是否因为没有真正理解这门课的真正目的而错过了什么?


答案 1

StringJoiner非常有用,当您需要在 .Stream

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

final List<String> strings = Arrays.asList("Foo", "Bar", "Baz");

使用起来要简单得多

final String collectJoin = strings.stream().collect(Collectors.joining(", "));

就像使用:StringBuilder

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

编辑6年后正如评论中所指出的,现在有更简单的解决方案,例如,当时还没有可用的解决方案。但用例仍然是一样的。String.join(", ", strings)


答案 2

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

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

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

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

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