Java 8 - Поток с Объектами и примитивными обертками - PullRequest
0 голосов
/ 01 ноября 2018

Я работаю с потоком Java 8 и пытаюсь изменить содержимое объекта в операции терминала forEach.

Проблемы, с которыми я здесь сталкиваюсь, заключаются в том, что я могу изменить содержимое объекта List<Employee>, но не могу изменить содержимое List<Integer>

Фрагмент кода выглядит следующим образом:

public static void streamExample() {

    List<Employee> listEmp = Arrays.asList(new Employee());
    listEmp.stream().forEach(a -> a.setEmptName("John Doe"));
    listEmp.stream().forEach(System.out::println);
    List<Integer> listInteger = Arrays.asList(2, 4, 6, 8, 12,17, 1234);
    listInteger.stream().filter(v -> v % 2 == 0).forEach(a -> a=a+1);
    listInteger.stream().forEach(System.out::println);

}

Мне интересно, что изменение не отражается в списке из-за распаковки целочисленного объекта при выполнении операции a=a+1, но я не уверен.

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Вы используете неоптимальный подход Stream. Подумайте о каждом шаге в Stream как об изменении существующего (или создании нового) элемента и верните его обратно в Stream. Наконец, вы получаете final результат и можете использовать один из методов final, чтобы завершить (и фактически запустить весь поток работающий) Stream:

List<Integer> listInteger = Arrays.asList(2, 4, 6, 8, 12, 17, 1234);
listInteger.stream().filter(v -> v % 2 == 0).forEach(a -> a = a + 1);
listInteger.stream().forEach(System.out::println);

Здесь у вас есть начальный массив. Вы хотите сделать следующее:

  1. Отфильтровать некоторые элементы (это не final шаг);
  2. Печать отфильтрованных элементов (это final шаг).

Для этого вам не нужно создавать Streams два раза. Используйте один:

Stream.of(2, 4, 6, 8, 12, 17, 1234)    // create stream (there're many way to do it)
      .filter(v -> v % 2 == 0)         // filter out required elements
      .map(v -> v + 1)                 // transform elements using given rule
      .forEach(System.out::println);   // finalize stream with printing out each element separately

Примечание: Stream.of(...) создает Stream, затем мы добавляем два шага к потоку filter и map и затем finalize или START созданный поток с forEach.

0 голосов
/ 01 ноября 2018

Вы присваиваете новое значение локальной переменной (a), так что это не влияет на источник второй Stream (ваш List<Integer>). Обратите внимание, что это не то, что вы делаете со своим List<Employee>, где вы вызываете метод установки для изменения элементов List.

Поскольку Integer s являются неизменяемыми, вы не можете изменить элементы вашего ввода List<Integer>.

Вместо этого вы можете создать новый List:

List<Integer> newList = 
    listInteger.stream()
               .map(v -> v % 2 == 0 ? v + 1 : v)
               .collect(Collectors.toList());

Или вы можете перейти по индексам вашего List и заменить некоторые элементы этого List:

IntStream.range(0,listInteger.size())
         .filter(i -> listInteger.get(i) % 2 == 0)
         .forEach(i -> listInteger.set(i, listInteger.get(i + 1));
...