#java #java-stream #collect
Вопрос:
Я тестирую collect
метод на потоках. В этом коде я пытаюсь построить одну строку из потока строк, используя a StringBuilder
в первом случае и объединение String
во втором случае. Я не понимаю, почему во втором случае получается пустая строка.
String[] strs = new String[] {"aaaaa", "bbbbbbb", "c", "dd"};
StringBuilder sb = Arrays.stream(strs).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
System.out.println(sb);
String s = Arrays.stream(strs).collect(String::new, String::concat, String::concat);
System.out.println(s);
Ответ №1:
Ну, причина, по которой это не работает, в том, что String
это непреложно.
String::new
является a Supplier<String>
, которое возвращает пустое String
значение .
И ваш накопитель и объединитель не могут его изменить, поскольку String
он неизменен.
Ваш код имеет тот же эффект, что и:
String s = new String ();
for (String str : strs) {
s.concat(str);
}
Вызовы для concat
создания новых String
s и не влияют на значение результата String
.
Поскольку String
является неизменяемым, вы можете использовать неизменяемое сокращение (т. Е. Использовать reduce
вместо collect
):
String s = Arrays.stream(strs).reduce("",String::concat);
Это приведет к тому же результату, что и:
String s = "";
for (String str : strs) {
s = s.concat(str);
}
Комментарии:
1. Хорошо, итак, метод сбора производит изменяемое сокращение. Спасибо, я думал, что он вел себя точно так же, как метод сокращения.