JHusker
JHusker

Reputation: 3

Are for-loops conditions able to be changed midloop?

In java programming: I have something along the lines of

ArrayList<String> list = new ArrayList<String>();

int listSize = list.size();

for(int x = 0; x< listSize; x++){
    list.remove(x);
    listSize = list.size();
}

will this work well enough? or will the for loop keep running. Thanks!

Upvotes: 0

Views: 75

Answers (4)

user1973108
user1973108

Reputation:

Technically, the computer science course would likely tell you to do it something like this:

public void solve() {
    ArrayList<String> list = new ArrayList<String>();
    Iterator iter = list.iterator();
    while(iter.hasNext()) {
        System.out.println("Next value is: " + iter.next());
        iter.remove();
    }
}

Upvotes: 0

jordaniac89
jordaniac89

Reputation: 574

Why not do it in a "while" loop?

ArrayList<String> list = new ArrayList<String>();

int listSize = list.size();

while(list.size() != 0){
    list.remove(x);
}

Upvotes: 0

Ashton
Ashton

Reputation: 11

The loop won't keep running and it will end without any exception. But the result may not what you expect. Besides "ArrayList#clear()" or Iterator way to remove all elements from one array. You can also try below codes, just remove "x++" from your loop condition.

ArrayList<String> list = new ArrayList<String>();

int listSize = list.size();

for(int x = 0; x< listSize;){
  list.remove(x);
  listSize = list.size();
}

Upvotes: 1

Makoto
Makoto

Reputation: 106440

I'm a bit concerned at what you're attempting to do here. Any time someone wants to remove items from a collection in a loop without using an Iterator, alarms usually go off.

So, to answer the question as stated: If you change your loop invariant, then you'll get some funky behavior. This is why it's often called an "invariant"; you don't want to change it. You're certainly welcome to, but you're playing with fire here.

But, let's assume that we have a list of 5 elements in it and we execute your code as is.

List<String> stringList = Arrays.asList("word", "another word", "let's go", "keep it up", "get moving");

int length = stringList.size();

for(int i = 0; i < length; i++) {
    System.out.println(stringList.remove(i));
    length = stringList.size();
}

System.out.println("done");

If you're expecting it to print out every word in the list, then think again. It will skip every element because we are changing the content of the list while iterating over it. When deleting elements from an ArrayList, the underlying implementation will shift over elements to the left in where it was deleted. So, if you delete from position 0, every element now lives to the left of its original position (so element 1 is now element 0).

A quick run-through:

  • First iteration, i = 0; "word" is removed. Size is changed to 4, i increases to 1.
  • Second iteration, i = 1; "let's go" is removed. Size is changed to 3, i increases to 2.
  • Third iteration, i = 2; "get moving" is removed. SIze is changed to 2, i increases to 3.
  • No further iteration happens as the condition is not satisfiable.

If you want to cleanly remove all items from the collection without printing them out, then ArrayList#clear() is what you're looking for. If you want to remove elements one at a time, then use an Iterator instead:

List<String> stringList = new ArrayList<>(Arrays.asList("word", "another word", "let's go", "keep it up", "get moving"));

for(Iterator<String> stringIterator = stringList.iterator(); stringIterator.hasNext(); ) {
    System.out.println(stringIterator.next());
    stringIterator.remove();
}

System.out.println("done");

Upvotes: 2

Related Questions