반복 집합 삭제 요소

6257 단어 listcollection
더 읽 기
1. 아래 표 시 된 요소 에 따라 요 소 를 삭제 합 니 다.
1. 테스트 코드

		ArrayList list = new ArrayList(Arrays.asList("a", "b", "c", "d"));
		for(int index = 0 ; index < list.size() ; index++){
			if(Objects.equals("a", list.get(index))){
				list.remove(index);
			}
		}
		System.out.println(String.valueOf(list));

2. 실현 원리

    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     * 
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    //             。
    //         (   1)。
    public E remove(int index) {
        rangeCheck(index); //     ,index            

        modCount++; //     
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        //  index+1 numMoved      index    
        //   index      ,          null,  GC
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }


3. 기타 상황
단일 요 소 를 삭제 하면 이 방식 을 사용 할 수 있 지만 여러 요소 의 경우 에는 사용 할 수 없습니다.
하나의 요 소 를 삭제 하면 배열 의 크기 와 원래 요소 의 아래 표 시 는 변 하기 때 문 입 니 다.그 에 상응하는 처 리 를 해 야 합 니 다.

		ArrayList list1 = new ArrayList(Arrays.asList("a", "b", "c", "d"));
		for(int index = 0 ; index < list1.size() ; index++){
			//    index = 0   a    ,      3,b     0,        c,      
			list1.remove(index);
		}
		System.out.println(String.valueOf(list1));

둘째, foreach
1. 코드 구현

		for (String s : list) {
		    if (s.equals("a"))
		        list.remove(s);
		} 

실행 중 이상 던 지기
Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) at java.util.ArrayList$Itr.next(ArrayList.java:831)
2. 이상 분석

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

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();//    831   
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
}

포 지 셔 닝 이상 정 보 를 옮 겨 다 니 는 과정 에서 chcek 가 진행 되 었 습 니 다.

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

modCount 실제 배열 을 조작 하 는 횟수, expected ModCount 예상 조작 횟수
초기 화

        int expectedModCount = modCount;

그러나 옮 겨 다 니 면서 reove 작업 을 수행 하여 modCount + 1 을 실 행 했 습 니 다. expected ModCount 와 일치 하지 않 습 니 다.
3. 요 소 를 삭제 하 는 방법 은 왜 Next 를 사용 합 니까?
자바 foreach 실현 원리
중 foreach 는 실질 적 으로 Iterator 의 호출 실현 입 니 다.

    /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * 

The returned iterator is fail-fast. * * @return an iterator over the elements in this list in proper sequence */ public Iterator iterator() { return new Itr(); } /** * An optimized version of AbstractList.Itr */ private class Itr implements Iterator {}


요소 삭제 실현 과정

    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }


Array List 의 Iterator 방법 을 호출 하여 내부 에서 실 현 된 정적 클래스 Itr 를 되 돌려 주 었 다 고 볼 수 있 습 니 다.
foreach 과정 에서 Iterator 의 next 작업 과정 에서 다음 요 소 를 가 져 오기 전에 한 번 씩 검 사 를 합 니 다.
수정 작업 을 동시에 할 수 없 는 이상 을 던 집 니 다.
3. Iterator

		Iterator iterator = list.iterator();
		while(iterator.hasNext()){
			if(StringUtils.isNotEmpty(iterator.next())){
				iterator.remove();
			}
		}

집합 을 Iterator 로 바 꾸 고 Iterator 를 통 해 집합 삭제 작업 을 합 니 다.

좋은 웹페이지 즐겨찾기