왜 foreach 순환 에서 JAVA 집합 은 요 소 를 추가 하거나 삭제 할 수 없 습 니까?
4416 단어 JAVAforeach 순환집합 하 다.
에서 집합 작업 에 대해 다음 과 같은 규정 이 있다.
[강제]있 지 마. foreach 순환 에서 원소 의 remove/add 조작remove 원소 사용 Iterator 방식,동시 다발 작업 이 필요 합 니 다. Iterator 대상 잠 금.
public class SimpleTest {
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
//
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("1".equalsIgnoreCase(item)) {
iterator.remove();
}
}
//
for (String item : list) {
if ("2".equals(item)) {
list.remove(item);
}
}
}
}
2.원인 분석순환 하거나 교체 할 때 먼저 교체 인 스 턴 스 를 만 듭 니 다.이 교체 인 스 턴 스 의 expected ModCount 는 집합 적 인 modCount 입 니 다.
교체 기 가 이성 hashNext()/next()를 다음 요 소 를 옮 겨 다 닐 때마다 modCount 변 수 는 expected ModCount 값 과 같 는 지,같 으 면 옮 겨 다 니 는 지 확인 합 니 다.그렇지 않 으 면 이상 을 던 집 니 다.
순환 에 요 소 를 추가 하거나 삭제 하면 집합 한 add,reove 방법[modCount 증가 또는 감소]을 직접 호출 합 니 다.그러나 이 방법 들 은 교체 인 스 턴 스 의 expected ModCount 를 수정 하지 않 고 교체 인 스 턴 스 에서 expected ModCount 와 modCount 의 값 이 같 지 않 습 니 다.Concurrent ModificationException 이상 을 던 집 니 다.
그러나 교체 기 에 있 는 reove,add 방법 은 집합 적 인 reove,add 방법 을 호출 한 후 expected ModCount 를 modCount 로 다시 할당 하기 때문에 교체 기 에 요 소 를 추가 하고 삭제 하면 정상적으로 작 동 할 수 있 습 니 다.
Array List 의 내부 개인 클래스 Itr,ListItr 의 소스 코드 를 참고 할 수 있 습 니 다.
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
//
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
3.관련 지식 소개3.1.빠 른 실패(fail-fast)는 무엇 입 니까?
빠 른 실패(fail-fast) 예. Java 집합 적 인 오류 검출 메커니즘.스토리 보드 가 집합 을 옮 겨 다 닐 때 다 중 스 레 드 에서 작업 할 수 있 습 니 다.안전 실패(fail-safe)의 집합 류 가 실 행 될 수 있 습 니 다. fail-fast 메커니즘,Concurrent ModificationException 던 지기 이상 하 다
또한,단일 스 레 드 에서 옮 겨 다 니 는 과정 에서 집합 대상 의 내용 을 수정 하면 트리거 됩 니 다. fail-fast 메커니즘.
다 중 스 레 드 에서 스 레 드 가 있 으 면 1 집합 을 옮 겨 다 니 고 있 습 니 다.이 때 스 레 드 입 니 다. 2 집합 에 대한 수정(추가,삭제,수정)또는 스 레 드 1 옮 겨 다 니 는 과정 에서 집합 을 수정 하면 스 레 드 를 초래 할 수 있 습 니 다. 1 Concurrent ModificationException 던 지기 이상 하 다
3.2.안전 실패(fail-safe)는 무엇 입 니까?
스토리 보드 보안 실패 메커니즘 의 집합 용 기 를 채취 하여 옮 겨 다 닐 때 집합 내용 에 직접 접근 하 는 것 이 아 닙 니 다.따라서 옮 겨 다 니 는 과정 에서 원래 집합 에 대한 수정 은 교체 기 에 의 해 감지 되 지 않 기 때문에 Concurrent ModificationException 을 버 리 지 않 습 니 다. 이상 하 다
foreach 순환 에서 왜 JAVA 집합 이 요 소 를 추가 하거나 삭제 할 수 없 는 지 에 대한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 JAVA 집합 이 요 소 를 추가 하거나 삭제 하 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 도 많은 관심 을 가 져 주시 기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.