How to remove an object from a stream in the foreach method?

I have arrays: arrAand arrB. arrAand arrB- these are lists of objects of different types, and the function addconverts the objects Ainto objects B. I want to add every object from arrA to arrB and remove this object from arrA. I am trying to do this downstream:

arrA.stream().foreach(c -> {arrB.add(c); arrA.remove(c);});

when I do this, two things happen:

  • not all objects are passed from arrA to arrB.
  • after several iterations, null pointer exception.

i believes that the length of the array decreases after each call remove(), and the iteration counter increases (only objects with odd indices are passed to arrB)

Now I can solve this by copying the array in one stream call, and then delete the objects in the second stream call, but this does not seem right for me.

What would be the correct solution to this problem?

EDIT. Additional information: in a real implementation, this list, if previously filtered

arrA.stream().filter(some condition).foreach(c -> {arrB.add(c); arrA.remove(c);});

and its called several times to add elements that satisfy different conditions in different lists ( arrC, arrDetc.), but each object can be in only one list

+4
source share
5 answers

Streams are designed for more functional use, preferably your collections are immutable.

The non-stream method would be:

arrB.addAll(arrA);
arrA.clear();

Streams, , :

arrB.addAll(arrA.stream().filter(x -> whatever).toList())

arrA ( @Holgar ).

arrA.removeIf(x -> whatever)

, :

Map<Boolean, XXX> lists = arrA.stream()
  .collect(Collectors.partitioningBy(x -> whatever));
arrA = lists.get(false);
arrB = lists.get(true);

:

List<XXX> toMove = arrA.stream().filter(x->whatever).toList();
arrA.removeAll(toMove);
arrB.addAll(toMove);
+9

, foreach - , for (A a: arrA) .

, plain while - ( ).

Iterator<A> it = arrA.iterator()
while (it.hasNext()) {
    A a = it.next();
    if (!check(a))
        continue;
    arrB.add(a);
    it.remove();
}

/ arrA.

+3

, remove() .

Right. for-each-loop , . . . forEach - , .

, . 0, 1 2. 0 , , 0 ( 1) 1 ( 2), 1, . 2, , , ( ), , .

:

  • List .
  • , .
+1

I don't think you can remove from arrA while you iterate over it.

You can get around this by wrapping it in a new ArrayList <> ();

new ArrayList <> (arrA) .stream (). foreach (c → {arrB.add (c); arrA.remove (c);});

0
source

You can just do Collections.addAll. Then when is it over. just call clear () on arrA.

-1
source

Source: https://habr.com/ru/post/1654348/


All Articles