java for-each本质--不能增加和删除,但是可以修改当前元素


java for-each的本质是使用迭代器实现

1.案例


@Test
	public void testForEach() {
		List strLinkedList = new LinkedList<>();
		strLinkedList.add("aaaa");
		strLinkedList.add("bbb");
		strLinkedList.add("cccc");
		System.out.println("strLinkedList.size:" + strLinkedList.size());
		for (String str : strLinkedList) {
			System.out.println("strLinkedList.size:" + strLinkedList.size());
			if (str.equals("aaaa")) {
				strLinkedList.remove("aaaa");//error,ConcurrentModificationException
			}else if(str.equals("cccc")){
				strLinkedList.remove("cccc");//error,ConcurrentModificationException
			}
			str = "mmmm";//ok
		}
	}

2.上面的代码会报ConcurrentModificationException异常

3.原因分析

每次进入for (String str : strLinkedList) 时,会调用java.util.LinkedList.ListItr.next()方法;

 public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

下面看一下checkForComodification()方法

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }


因为checkForComodification()方法对集合的长度进行了判断,所以出现异常


4.躲避长度判断,执行增加和删除的方法。

在下一次进入循环之前就退出循环,这样就能既能实现增加和删除操作,又不会报错

@Test
	public void testForEach() {
		List strLinkedList = new LinkedList<>();
		strLinkedList.add("aaaa");
		strLinkedList.add("bbb");
		strLinkedList.add("cccc");
		System.out.println("strLinkedList.size:" + strLinkedList.size());
		for (String str : strLinkedList) {
			if (str.equals("bbb")) {
				strLinkedList.remove("aaaa");// OK
				System.out.println("strLinkedList.size:" + strLinkedList.size());
				break;
			}
		}
		System.out.println("strLinkedList.size:" + strLinkedList.size());
	}

输出结果

strLinkedList.size:3
strLinkedList.size:2
strLinkedList.size:2






java for-each的本质是使用迭代器实现

你可能感兴趣的:(技术积累,java,for-each不能增加和删除,但是可以修改当前元素)