Могу ли я изменить элементы, повторяя их с помощью Iterable.forEach (Consumer)? - PullRequest
0 голосов
/ 25 апреля 2019

Могу ли я изменить элементы, повторяя их с помощью Iterable.forEach (Consumer)? Или в Consumer.accept (E) я могу только читать элементы базового Iterable, но не изменять их?

Если я могу изменить их, каков правильный синтаксис?

ArrayDeque d = new ArrayDeque<Integer>();
d.add(1);
d.add(2);
d.add(3);
d.add(4);

Consumer<Integer> cons = (e)->{e = e*10;}; // compiles!

d.forEach(cons);

System.out.println(d); // 1 2 3 4 not 10 20 30 40

Ответы [ 4 ]

2 голосов
/ 25 апреля 2019

То, что вы пытаетесь сделать, аналогично:

for (Integer e : d) {
   e = e * 10;
}

Но присвоение e не меняет его значения в деке.

Чтобы делать то, что вы хотите, делайте это.

 d = d.stream().map(a -> a * 10).collect(
            Collectors.toCollection(ArrayDeque::new));
 System.out.println(d);
1 голос
/ 25 апреля 2019

Нет, вы не можете. Согласно документации для ArrayDeque:

Итераторы, возвращаемые методом итератора этого класса, не подвержены сбоям: если в любой момент после создания итератора модификация изменяется любым способом, кроме как через собственный метод remove итератора, итератор обычно выдает ConcurrentModificationException.

1 голос
/ 25 апреля 2019

Нет, вы не можете изменять элементы при использовании forEach, так как action равно Consumer, что только accepts значение. Пример фрагмента для forEach method

default void forEach(Consumer<? super T> action)
 for (T t : this)
     action.accept(t);

Главное, на чем нужно сосредоточиться, это не генерировать никакого значения.

1 голос
/ 25 апреля 2019

forEach принимает параметр Consumer, который ничего не возвращает, и, согласно вашему примеру, каждый e является копией элемента в ArrayDeque, поэтому вы не можете заменить элементы с помощью forEach.

Если вы хотите сделать e*10 для каждого элемента для одной задачи (например, распечатать их), вы можете преобразовать ArrayDeque в Stream и использовать map ():

d.stream().map(e -> e*10).forEach(e -> System.out.println(e));

Это покажет, что каждый элемент в Deque был умножен на 10.

Если вы действительно хотите заменить элементы в ArrayDeque,

d = d.stream().map(e -> e*10).collect(Collectors.toCollection(ArrayDeque::new));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...