Вы не видите StringBuilder
, потому что результат использования StringBuilder
равен String
. StringBuilder
используется за кулисами.
Пример
String[] input = { "Hell", "oW", "orld" };
String joined = Stream.of(input).collect(Collectors.joining());
System.out.println(joined); // prints: HelloWorld
Если вы сделаете это без потоковой передачи, вы сделаете:
StringBuilder buf = new StringBuilder();
for (String s : input)
buf.append(s);
String joined = buf.toString();
Это также то, что делает поток. Если вы посмотрите на исходный код joining()
, вы увидите:
public static Collector<CharSequence, ?, String> joining() {
return new CollectorImpl<CharSequence, StringBuilder, String>(
StringBuilder::new, StringBuilder::append,
(r1, r2) -> { r1.append(r2); return r1; },
StringBuilder::toString, CH_NOID);
}
Как видите, он также использует new StringBuilder()
,append(CharSequence s)
и toString()
.
Две другие перегрузки, joining(CharSequence delimiter)
и joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
, используйте StringJoiner
вместо StringBuilder
.
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
return joining(delimiter, "", "");
}
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);
}