ArrayList.clear ()와 ArrayList.removeAll ()의 차이점은 무엇입니까?


283

그는 가정하면 arraylist같이 정의되어 ArrayList<String> arraylist있다 arraylist.removeAll(arraylist)동등 arraylist.clear()?

그렇다면 clear()배열 목록을 비우는 데 메소드가 더 효율적 이라고 가정 할 수 있습니까?

arraylist.removeAll(arraylist)대신 에 사용상의주의 사항 이 arraylist.clear()있습니까?


이 질문에 대한 가능한 추론 : 언제 하나 대신 다른 하나를 사용할 수 있습니까?
Corey Ogburn

3
@Corey : 언제 모두가 사용하고 싶 arraylist.removeAll(arraylist)습니까? 그렇게 할 이유가 전혀 없습니다.
Joachim Sauer

@Joachim Sauer 그것이 바로 내가 확인하고 싶었던 것입니다. 고마워 +2 그러나 사이의 차이 elementData[i] = nulle.remove()의미는?
ateiob

arrList.removeAll(arrList)대신 해야 할 확실한 이유가 없습니다 arrList.clear(). arrList1.removeAll(arrList2)다른 문제입니다.
블라드

3
removeAll ()의 구현 만이 라인으로 시작한다면,이 전체 토론은 훨씬 더 재미 있었을 것입니다 !!! if (c == this && !isEmpty()) { clear(); return true; }. 패치로 OpenJDK에 제출해야합니다! ;-)
Julius Musseau

답변:


396

의 소스 코드 clear():

public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

에 대한 소스 코드 :에 removeAll()정의 된대로 AbstractCollection:

public boolean removeAll(Collection<?> c) {
    boolean modified = false;
    Iterator<?> e = iterator();
    while (e.hasNext()) {
        if (c.contains(e.next())) {
            e.remove();
            modified = true;
        }
    }
    return modified;
}

clear() 추가 메소드 호출을 모두 처리 할 필요가 없으므로 훨씬 빠릅니다.

그리고 Atrey가 지적했듯이, O (n )과 반대로 O (n 2 ) c.contains(..)의 시간 복잡성을 증가시킵니다 .removeAllclear


29
c.contains(...)작업의 시간 복잡성 을 제곱하면이 답변이 완료됩니다.
Atreys

8
이 소스는 강력합니다. (다른 모든 답변 : 소스, Luke를 사용하십시오.) clear ()를 한 줄로 구현할 수있는 방법에 주목하십시오. size = 0; 그러나 가비지 수집은 배열의 도달 할 수없는 부분의 요소를 수집하는 것을 알지 못합니다.
Julius Musseau

2
e.remove ()는 훨씬 더 복잡합니다! e.remove ()는 c.contains (...)와 마찬가지로 복잡성을 제곱합니다. ArrayList에서 e.remove ()는 ArrayList.remove (int index)를 호출하여 배열의 나머지 부분을 1만큼 이동시켜야합니다.
Julius Musseau

1
@ateiob e.remove ()는 두 가지 추가 메소드 호출, 범위 검사 및 객체 리턴 (내부 AbstractList.Itr.remove()및 내부 ArrayList.remove(int))입니다.
Atreys

2
@julius이 작업을 수행 한 경우 : size = 0; elementData = new Object[10];백업 배열에 외부 참조가 없으므로 나머지는 모두 가비지 수집됩니다.
corsiKa

51

시간 복잡성 ArrayList.clear() 이다 O(n)와의 removeAllIS O(n^2).

예, ArrayList.clear훨씬 빠릅니다.


15

clear()방법은 단일의 모든 요소를 ​​제거합니다 ArrayList. 배열 요소를로 설정하기 때문에 빠른 작업 null입니다.

removeAll(Collection)에서 상속 방법은 AbstractCollection, 당신이 메소드를 호출 컬렉션에서 인수 컬렉션의 모든 요소를 제거합니다. 관련 컬렉션 중 하나를 검색해야하기 때문에 상대적으로 느리게 작동합니다.


일부 요소가 아닌 모든 요소를 ​​null로 설정한다고 생각했습니다. 그렇지 않은 경우 어떤 요소를 null로 설정해야하는지 어떻게 결정 했습니까?
Farid

2
@Farid 죄송합니다. 제 영어는 너무 비공식적입니다. 실제로 모든 요소를 ​​null로 설정한다는 것을 의미했습니다. 내가 고칠 게요!
어니스트 프리드먼

7

검사는 인수가 전달 된 경우에하는 특정 최적화가되지 않는 한에 removeAll()콜렉션 자체는 (내가는 매우 의심 이러한 최적화가 있음)가 될 것입니다 상당히 간단한보다 느리게.clear() .

그 외에도 (그리고 적어도 똑같이 중요하다) : arraylist.removeAll(arraylist)혼란스럽고 혼란스러운 코드입니다. "이 컬렉션을 지 웁니다"라는 말은 거꾸로 말합니다. 이해할 수있는 것보다 어떤 이점이 arraylist.clear()있습니까?


7

그들은 다른 목적으로 사용됩니다. clear()클래스의 인스턴스를 지우고 removeAll()주어진 모든 객체를 제거하고 작업 상태를 반환합니다.


추가 참조를 위해 위의 내용을 읽을 수있는 자료를 제공해 주
시겠습니까?

1
@KasunSiyambalapitiya 허용되는 답변 은 어떻습니까? 둘에 대한 소스 코드가 포함되어 있습니까?
Abdul

5

clear() 기본 배열을 거치고 각 항목을 null로 설정합니다.

removeAll(collection)컬렉션 및 컬렉션이 있는지 확인하는 ArrayList를 거치게됩니다 remove(Object).

clear()비교하지 않기 때문에 removeAll보다 더 빠르다고 생각합니다 .


2

삭제할 요소를 반복하지 않기 때문에 지우기가 더 빠릅니다. 이 방법은 모든 요소를 ​​삭제할 수 있다고 가정 할 수 있습니다.

Remove all반드시 목록의 모든 요소를 ​​삭제하는 것은 아니며 매개 변수로 제공된 요소 만 삭제해야합니다. 따라서 삭제해서는 안되는 것들을 유지하기 위해 더 많은 노력이 필요합니다.

설명

'루프'는 요소를 유지할지 여부를 확인할 필요가 없음을 의미합니다. 참조를 설정할 수 있습니다null제공된 요소 목록을 검색하지 않고 삭제할 수 있습니다.

Clear보다 빠릅니다 deleteall.


1
나는 그것이 ArrayList.clear()반복 되어야한다고 확신합니다 .
Joachim Sauer

@JVerstry clear () ArrayList에서 제거하는 요소를 삭제하지 않습니까?
ateiob

1
잘못, clear는 내부 배열을 반복하고 가비지 수집기가 작업을 수행 할 수 있도록 모든 참조를 null로 설정합니다.
devconsole

1
@Joachim, @devconsole : 그는 매개 변수로 주어진 목록을 반복 / 반복 할 필요가 없다고 생각했습니다. target.removeAll(param)반복 param하고 호출 target.contains(...)할 호출 target합니다.
블라드

2
-3은 약간 가혹합니다. JVerstry가 원한다면 반복되지 않는 자체 Java 구현을 처음부터 작성할 수있었습니다. clear () 루프없이 O (1)에서 구현 될 있지만 removeAll ()은 어떤 종류의 O (n) 알고리즘을 가져야하며, 모든 요소를 ​​검사하지 않고 removeAll () API의 계약을 충족시킬 방법이 없습니다.
Julius Musseau

1

clear ()가 훨씬 더 효율적입니다. 단순히 모든 항목을 제거합니다. removeAll (arraylist)을 사용하면 arraylist의 모든 항목을 검사하여 arraylist에 있는지 확인하기 때문에 더 많은 작업이 필요합니다.


-8

Array => 런타임에 공간이 배열 변수에 할당되면 할당 된 공간을 확장하거나 제거 할 수 없습니다.

ArrayList => arraylist에서는 그렇지 않습니다. ArrayList는 런타임에 커지거나 줄어들 수 있습니다. 할당 된 공간은 런타임에 최소화하거나 최대화 할 수 있습니다.


이것은 ArrayList.clear ()와 ArrayList.removeAll ()의 차이점이 아니라 Array와 ArrayList의 차이점이 아닌 질문에 대답하지 않습니다.
Pierre

이 답변은 필요하지 않습니다. 그것은 그 질문에 관한 것이 아닙니다.
Serafim Costa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.