Короткий ответ
Вы предполагаете, что после этого момента:
Stream<String> jFilter = strStream.filter(str -> str.startsWith("J"));
, что возвращается новый поток элементов, начинающихся с "J", т.е. только Java
.Однако это не случай;
потоки ленивый т.е. они не выполняют никакой логики , если не указано иное при терминальной операции.
Фактическое выполнение конвейера потоканачинается при вызове toArray()
, и поскольку список был изменен до начала операции терминала toArray()
, результатом будет [Java, JavaScript, JQuery]
.
Longer Answer
здесь часть документация , в которой упоминается это:
Для потоковых источников с хорошим поведением источник может быть изменен до начала работы терминала, и эти изменения будут отражены в охватываемых элементах.Например, рассмотрим следующий код:
List<String> l = new ArrayList(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = sl.collect(joining(" "));
Сначала создается список, состоящий из двух строк: «one»;и два".Затем создается поток из этого списка.Далее список модифицируется добавлением третьей строки: «три».Наконец элементы потока собираются и объединяются.Поскольку список был изменен до начала операции сбора терминала, результатом будет строка «один два три».Все потоки, возвращаемые из коллекций JDK и большинства других классов JDK, ведут себя хорошо;