laitimes

The difference between for and foreach

author:Program Zoji

Before a colleague suddenly asked me a question, said in the foreach can not delete the elements in the list, I was roughly said whether it can be deleted, and the reason; next let's explore whether it can be so;

(1) Iterate over elements

First, let's take a piece of code as an example:

String array = {"1", "2", "3"};

for (String i : array) {

System.out.println(i);

}

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

for (String i : list) {

System.out.println(i);

}
      

The result after traversal is as follows:

1

2

3

111

222

333
      

The results are beyond doubt.

Let's take a look at the compiled source code (idea comes with you, open your source file in the target package):

String array = new String{"1", "2", "3"};

String var2 = array;

int var3 = array.length;

for(int var4 = 0; var4 < var3; ++var4) {

String i = var2[var4];

System.out.println(i);

}

ArrayList<String> list = new ArrayList;

list.add("111");

list.add("222");

list.add("333");

Iterator var7 = list.iterator;

while(var7.hasNext) {

String i = (String)var7.next;

System.out.println(i);

}
      

It can be seen that the traversal of the array uses the original for loop, and the collection uses the Iterator iterator.

(2) Delete the element

Oh k! Next, let's delete the element:

Using the for loop:

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

log.info(list.toString);

for (int i = 0; i <list.size; i++) {

list.remove("222");

}

log.info(list.toString);
      

outcome:

11:11:52.532 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]

11:11:52.539 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 333]
      

Apparently successful!

Using foreach:

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

log.info(list.toString);

for (String i : list) {

list.remove("222");

}

log.info(list.toString);
      

outcome:

11:50:48.333 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)

at java.util.ArrayList$Itr.next(ArrayList.java:859)

at com.xiaolinge.com.hello.HelloWord.main(HelloWord.java:30)
      

Obviously wood has success!

cause:

Each iteration inside the iterator records the modcount inside the List as the expected value, and then in each loop compares the expected value to the list's member variable, modCount, but normal

list.remove

The call is for List's resolve, at this time

modcount++

, but the expected value of the recorded in the iterator = has not changed, so an error will be reported.

If you want to delete an element, you need to use the move method inside the iterator:

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

log.info(list.toString);

Iterator<String> it = list.iterator;

while (it.hasNext){

String next = it.next;

//if外使用list的remove方法还是会报错的

if(next.equals("222")){

it.remove;//这里使用的是迭代器里面的remove方法,

// 当然如果使用list的remove方法在此删除质地感元素的话是成功的,比如:list.remove("222")

}

}

log.info(list.toString);
      

outcome:

12:06:14.042 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]

12:06:14.046 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 333]
      

(3) Modify the element

Using the original for:

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

log.info(list.toString);

for (int i = 0; i <list.size; i++) {

list.set(i,"444");

}

log.info(list.toString);
      

outcome:

12:12:56.910 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]

12:12:56.915 [main] INFO com.xiaolinge.com.hello.HelloWord - [444, 444, 444]
      

Oh k! Elements can be modified;

Using foreach:

ArrayList<String> list = new ArrayList<>;

list.add("111");

list.add("222");

list.add("333");

log.info(list.toString);

for (String i : list) {

i="444";

}

log.info(list.toString); 
      

outcome:

12:34:47.207 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]

12:34:47.211 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
      

See, no.

Spicy, modifying the element is not OK, is it okay to modify the attributes of the element? Let's take a look.

(4) Foreach modifies element properties

(for is not tested)

Create a student class:

public classStudent{

private int age;

publicintgetAge {

return age;

}

publicvoidsetAge(int age) {

this.age = age;

}

public String getName {

return name;

}

publicvoidsetName(String name) {

this.name = name;

}

private String name;

publicStudent{};

publicStudent(int age,String name){

this.age=age;

this.name=name;

}

} 
      

Oh k, next test the code:

Student student=new Student(1,"huge");

Student student1=new Student(1,"xiaoyao");

List<Student> studentList=new ArrayList<Student>;

studentList.add(student);

studentList.add(student1);

System.out.println(student.getName);

System.out.println(student1.getName);

for(Student stu:studentList)

{

stu.setName("jingtian");

}

System.out.println(student.getName);

System.out.println(student1.getName);
      

outcome:

huge

xiaoyao

jingtian

jingtian
      

484 is magical! You cannot modify the object, but you can modify the properties of the object.

summary

  • Both for and foreach can traverse arrays/collections, but for is more efficient in more complex loops.
  • foreach cannot delete/modify collection elements, but for can
  • Both foreach and for can modify the properties inside the element

So the for loop is more flexible in comparison.

From: https://blog.csdn.net/qq_40521656/article/details/90749927