과거에는 컬렉션을 안전하게 복사한다고 말했습니다.
public static void doThing(List<String> strs) {
List<String> newStrs = new ArrayList<>(strs);
또는
public static void doThing(NavigableSet<String> strs) {
NavigableSet<String> newStrs = new TreeSet<>(strs);
그러나 이러한 "복사"생성자, 비슷한 정적 생성 방법 및 스트림은 실제로 안전하며 규칙은 어디에 지정되어 있습니까? 안전하다는 말은 합리적으로 백업되고 결함이 없다고 가정 할 때 악의적 인 호출자에 대해 시행되는 Java 언어 및 컬렉션에서 제공 하는 기본 시맨틱 무결성 보장 SecurityManager
입니다.
나는이 방법을 던지는 행복 해요 ConcurrentModificationException
, NullPointerException
, IllegalArgumentException
, ClassCastException
, 등, 또는 심지어 매달려.
String
불변 유형 인수의 예로 선택 했습니다. 이 질문에 대해, 나는 자신의 문제가있는 가변 유형의 컬렉션에 대한 깊은 사본에 관심이 없습니다.
(명확하게하기 위해, 나는 오픈 JDK 소스 코드를 보면서 대한 대답의 몇 가지 종류가있다 ArrayList
하고 TreeSet
.)
NavigableSet
다른 Comparable
기반 컬렉션은 때로는 클래스가 compareTo()
올바르게 구현되지 않고 예외를 throw하는지 감지 할 수 있습니다 . 신뢰할 수없는 주장에 의해 당신이 무엇을 의미하는지는 불분명합니다. 당신은 악당이 나쁜 줄의 모음을 만들어 내고 그것을 당신의 모음으로 복사 할 때 나쁜 일이 발생했음을 의미합니까? 아니요, 컬렉션 프레임 워크는 매우 견고하며 1.2 이후로 사용되었습니다.
HashSet
(그리고 일반적으로 다른 모든 해시 컬렉션)의 정확성 / 무결성에 의존하는 hashCode
요소의 구현 TreeSet
및 PriorityQueue
에 따라 Comparator
(그리고 당신도 할 수 없습니다 존재하는 경우) 사용자 정의 비교를 적용하지 않고 동등한 복사본을 만들 EnumSet
특정의 무결성 신뢰 enum
클래스 파일, 그래서 생성하지, 컴파일 후 확인되지 않습니다 유형 javac
을 파괴하거나 손수.
new TreeSet<>(strs)
어디 strs
입니다 NavigableSet
. 결과적으로 TreeSet
의미를 유지하는 데 필요한 소스의 비교기를 사용 하므로 대량 사본이 아닙니다 . 포함 된 요소를 처리하는 것만으로도 괜찮다면 toArray()
갈 길입니다. 반복 순서를 유지합니다. “요소 가져 오기, 요소 유효성 검사, 요소 사용”에 능숙하면 복사 할 필요조차 없습니다. 모든 요소를 확인하고 모든 요소를 사용하려는 경우 문제가 시작됩니다. 그런 다음, 당신은 믿을 수 없다 TreeSet
사용자 정의 비교 w 사본
checkcast
각 요소에 대해 효과가있는 유일한 대량 복사 작업 toArray
은 특정 유형입니다. 우리는 항상 끝납니다. 일반 컬렉션은 실제 요소 유형을 알지 못하므로 복사 생성자가 비슷한 기능을 제공 할 수 없습니다. 물론, 당신은 올바른 사용을 위해 수표를 연기 할 수는 있지만, 귀하의 질문이 무엇을 목표로하는지 모르겠습니다. 요소를 사용하기 직전에 확인하고 실패하면 "의미 적 무결성"이 필요하지 않습니다.