Arrays.asList ()에서 만든 목록의 remove ()에서 UnsupportedOperationException이 발생합니다.


91

컬렉션 c1<MyClass>과 배열이 a<MyClass>있습니다. 나는 컬렉션에 배열을 변환하려고 c2하고 할 c1.removeAll(c2),하지만이 발생합니다 UnsupportedOperationException. 나는 것을 발견 asList()배열 클래스 반환의 Arrays.ArrayList클래스와이 클래스는 상속 removeAll()에서 AbstractList()그 구현이 발생합니다 UnsupportedOperationException.

    Myclass la[] = getMyClass();
    Collection c = Arrays.asList(la);
    c.removeAll(thisAllreadyExistingMyClass);

요소를 제거하는 방법이 있습니까? 도와주세요


답변:


173

Arrays.asListList배열 주위 에 래퍼를 반환합니다 . 이 래퍼는 크기가 고정되어 있으며 배열에 의해 직접 지원되며 이러한 호출 set은 배열을 수정하고 목록을 수정하는 다른 모든 메서드는 UnsupportedOperationException.

이 문제를 해결하려면 래퍼 목록의 내용을 복사하여 수정 가능한 새 목록을 만들어야합니다. 다음을 사용하는 ArrayList생성자를 사용하면 쉽습니다 Collection.

Collection c = new ArrayList(Arrays.asList(la));

1
java.util.Arrays asList()메서드 의 소스 코드를보고 있었는데 ArrayList. 그러나를 수행 System.out.println(list.getClass());하면 class java.util.Arrays$ArrayList. 그래서 그것은 or 메소드 ArrayList가없는 내부 클래스를 사용합니다 . 나는 하나 를 사용하는 대신 내부 클래스 를 갖는 것이 무엇 이며 왜 and 메소드 가 없는지 궁금합니다 . addremoveArrayListjava.util.ArrayListadd()remove()
Abdul

내 위의 댓글 수정 : addremove메서드가 있습니다
Abdul

1
@Abdul 고정 된 크기와 같은 것이 없기 때문입니다 java.util.ArrayList. List추가 또는 제거와 같은 불법적 인 작업을 수행하고 ArrayList해당 요구 사항을 충족하지 않는 경우 예외가 발생 하는 구현을 원합니다 .
Etienne de Martel 2015 년

@Abdul은 Arrays.asList그냥 래퍼를 만듭니다 List. 그러나 여전히 java.util.List이므로 해당 메서드가 있어야합니다. 그러나 다른 크기의 새 어레이를 생성 할 수 있기 때문에 적용 할 수 없습니다. 여전히 할 수있는 수정은 반환 된 List와 원래 배열을 통해 수행 할 수 있기 때문에 수행 할 수 없습니다. 반환 된 List가 기본적으로 원래 배열 참조를 버리도록 변경 될 수 있다면 불가능합니다.
Adam Hošek

13

예,은 ( Arrays.asList(..)는) 확장하거나 축소 할 수없는 컬렉션입니다 (원래 배열이 지원하고 크기를 조정할 수 없기 때문입니다).

요소를 제거 new ArrayList(Arrays.asList(..)하려면 배열에서 직접 요소를 만들 거나 제거합니다 (효율성이 떨어지고 쓰기가 더 어렵습니다).


+1이 대답은 유일한 정답입니다. Arrays.asList ()는 수정할 수없는 목록을 반환합니다 . 이것이 예외를 발생시키는 것입니다. "배열에 의해 지원"되는 것과는 아무 관련이 없습니다. 모든 ArrayList는 배열에 의해 지원됩니다.
Bohemian

1
그러나 문서를 더 읽어 보면 실제로 수정할 수 없다는 것을 알게 될 것입니다 ... "지정된 배열에 의해 지원되는 고정 크기 목록을 반환합니다. (반환 된 목록이 배열에"쓰기 "로 변경됨) .) "-1, 에티엔의 말이 맞습니다.
Steven Schlansker 2011 년

1
@Steven 네, 그렇기 때문에 "수정 불가능"또는 "읽기 전용"이 아닌 "고정 크기"라고 표시됩니다. 사실, 나는 그것을 반영하기 위해 지금 내 대답을 편집 할 것입니다.
Etienne de Martel 2011 년

1
@Bohemian, 반환 된 컬렉션은 'set'메서드를 호출 할 수 있기 때문에 실제로 '수정 가능'합니다.
javalearner

2
그런 식으로 nits를 선택하려면 "코드에 UnsupportedOperationException 문이 있기 때문에 UnsupportedOperationException을 throw합니다"와 같은 멍청한 말을하는 것이 좋습니다. API 소비자는 어떤 AbstractBlah 슈퍼 클래스가 예외를 던지는 지 신경 쓰지 않고, 사용하는 클래스의 계약과 기대치가 무엇인지 신경을 씁니다. JVM v + 1에서는 예외가 발생하는 위치에서 클래스 라이브러리가 변경 될 수 있지만 계약은 변경되지 않습니다.
Steven Schlansker 2011 년

7

이것이 Array.asList()작동 방식 입니다. 어레이에 의해 직접 지원되기 때문입니다. 완전히 수정 가능한 목록을 얻으려면 컬렉션을 직접 만든 컬렉션으로 복제해야합니다.

Collection c = new ArrayList(Arrays.asList(la))

1
목록은 수정 가능하지만 set ()을 통해서만 가능합니다. 반환 된 컬렉션은 고정 크기입니다.
javalearner

실제로 수정할 수 없다고 말한 적이 없습니다. (완전히) 수정 가능한 목록을 얻으려면 ArrayList. 하지만 그 차이는 분명하지 않았을 것입니다. :-) 목록이 수정 가능한지 여부가 정의의 문제인지 여부는 "반 수정 가능"하지만 내 관점에서 완전히 수정할 수는 없습니다.
henko 2011 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.