0
List<Integer> listArr = new ArrayList<>();

        listArr.add(5);
        listArr.add(7);
        listArr.add(90);
        listArr.add(11);
        listArr.add(55);
        listArr.add(60);
for(int i = 0; i < listArr.size(); i++) {
            if (listArr.get(i) % 2 != 0) {
                listArr.remove(i);
            }
        }

I'm trying to remove all odd numbers from the ArrayList and it must be for or foreEach loop. The result would be 7, 90, 55, 60 for the numbers that are remaining in the ArrayList after loop is finished. When I set a condition:

if(listArr.get(i) % 2 == 0)

Everything is working fine. All even numbers are removed, but in the first example that's not the case for odd numbers. Why is this happening?

Vukasin
  • 23
  • 8

3 Answers3

3

Because when you remove a item in the arraylist, you've changed the list, try to iterate it in reverse mode. break down:

  1. when i = 0, your code removed it from list, then index 0 in your list is 7
  2. when i = 1, the index on 1 is 90, so your code doesn't remove it.
  3. when i =2, the index on 2 is 11, so your code remove it, then index on 2 in the list is 55,
  4. when i = 3, the index on 3 i 60, so it will be kept.

End of loop, that's why your code output what you see, and that's why you should run it in reverse mode

keshin
  • 534
  • 4
  • 8
1

You shouldn't edit list with for-loop(both add and remove), instead of use iterator like:

        List<Integer> listArr = new ArrayList<>();

        listArr.add(5);
        listArr.add(7);
        listArr.add(90);
        listArr.add(11);
        listArr.add(55);
        listArr.add(60);
        var it = listArr.iterator();
        while (it.hasNext()) {
            var n = it.next();
            if (n % 2 == 0) {
                it.remove();
            }
        }
Cwift
  • 300
  • 1
  • 6
0

The answer is just one simple line, indeed you can achieve it with many approaches with stream api, here we use Collector interface.

public class Main {
    public static void main(String[] args) {
    
        //question values
        List<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(7);
        list.add(90);
        list.add(11);
        list.add(55);
        list.add(60);
        
        //answer
        List<Integer> result = list.stream().collect(ArrayList::new, (u, v) -> {if(v % 2 == 0)           u.add(v);}, List::addAll);
        
        //validating result
        result.forEach(System.out::println);
    }
}

More over you can achive the same result with creating custom collector like below

public class OddNumbersCollector implements Collector<Integer, List<Integer>, List<Integer>> {
    @Override
    public Supplier<List<Integer>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<Integer>, Integer> accumulator() {
        return (u, v) -> {
            if(v % 2 == 0)
                u.add(v);
        };
    }

    @Override
    public BinaryOperator<List<Integer>> combiner() {
        return (u, v) -> {
            u.addAll(v);
            return u;
        };
    }

    @Override
    public Function<List<Integer>, List<Integer>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
    }
}

And answer int this case becomes

List<Integer> result = list.stream().collect(new OddNumbersCollector());

That's all, no need to extra efforts .

Lunatic
  • 1,519
  • 8
  • 24
  • @user16320675 beside this just Biconsumer instead of a consumer (at least in our planet is)do a simple bench marking and find the better performance, and there is no difference between ways cause either way you streaming so better to doing with collectors for having the result as list . – Lunatic Dec 27 '21 at 10:17
  • I know all of that with iteration and collection. The assignment is to go with something that is not that. So for loop or forEach. This is not the question about performance. – Vukasin Dec 28 '21 at 01:23