에서 자바 1.6 컬렉션 프레임 워크 문서 :
어떠한 수정 작업 (예를 지원하지 않는 컬렉션
add
,remove
및clear
)라고도 불가능한 . […] Collection 객체의 변경 사항이 표시되지 않음을 추가로 보장하는 컬렉션을 불변 이라고합니다 .
두 번째 기준은 저를 약간 혼란스럽게합니다. 첫 번째 컬렉션을 수정할 수없고 원래 컬렉션 참조가 삭제되었다고 가정 할 때 두 번째 줄에서 참조되는 변경 사항은 무엇입니까? 컬렉션에 포함 된 요소의 변경, 즉 요소의 상태를 의미합니까?
두 번째 질문 :
컬렉션을 변경할 수없는 경우 지정된 추가 보증을 제공하는 방법은 무엇입니까? 컬렉션의 요소 상태가 스레드에 의해 업데이트되는 경우 해당 상태의 업데이트가 변경 불가능한 컬렉션을 보유하는 스레드에서 표시되지 않는 것으로 충분합니까?
컬렉션이 변경 불가능하도록하려면 지정된 추가 보장을 어떻게 제공합니까?
답변
수정할 수없는 컬렉션은 일반적으로 다른 컬렉션의 읽기 전용보기 (래퍼)입니다. 추가, 제거 또는 지울 수 없지만 기본 컬렉션은 변경 될 수 있습니다.
변경 불가능한 컬렉션은 전혀 변경할 수 없습니다. 다른 컬렉션을 래핑하지 않고 자체 요소를 가지고 있습니다.
다음은 구아바의 인용문입니다. ImmutableList
Collections.unmodifiableList(java.util.List<? extends T>)
여전히 변경 될 수있는 별도의 컬렉션보기 인와 달리 의 인스턴스ImmutableList
는 자체 개인 데이터 를 포함하며 절대 변경되지 않습니다.
따라서 기본적으로 변경 가능한 컬렉션에서 변경할 수없는 컬렉션을 가져 오려면 해당 요소를 새 컬렉션에 복사하고 모든 작업을 허용하지 않아야합니다.
답변
차이점은 변경을 허용하는 불변 컬렉션에 대한 참조를 가질 수 없다는 것입니다. 수정할 수없는 컬렉션은 해당 참조를 통해 수정할 수 없지만 일부 다른 개체는 변경할 수있는 동일한 데이터를 가리킬 수 있습니다.
예 :
List<String> strings = new ArrayList<String>();
List<String> unmodifiable = Collections.unmodifiableList(strings);
unmodifiable.add("New string"); // will fail at runtime
strings.add("Aha!"); // will succeed
System.out.println(unmodifiable);
답변
Collection<String> c1 = new ArrayList<String>();
c1.add("foo");
Collection<String> c2 = Collections.unmodifiableList(c1);
c1
이다 변경 가능한 (즉,도 불가능한 도 불변 ).
c2
이다 불가능한 : 그 자체를 변경할 수 없습니다,하지만 난 변경할 나중에 경우 c1
다음 것을 변경에 표시됩니다 c2
.
이것은 c2
단순히 래퍼 c1
이며 실제로는 독립적 인 사본 이 아니기 때문 입니다 . Guava는 ImmutableList
인터페이스 와 일부 구현을 제공합니다 . 그것들은 실제로 입력의 복사본을 만드는 방식으로 작동합니다 (입력이 자체적으로 변경 불가능한 컬렉션이 아닌 경우).
두 번째 질문에 대해 :
컬렉션 의 가변성 / 불변성은 그 안에 포함 된 객체의 가변성 / 불변성에 의존 하지 않습니다 . 컬렉션에 포함 된 개체를 수정하는 것은 이 설명에 대한 “컬렉션 수정”으로 간주 되지 않습니다 . 물론 변경 불가능한 컬렉션이 필요한 경우 일반적으로 변경 불가능한 객체도 포함하기를 원합니다.
답변
이제 Java 9 에는 Immutable List, Set, Map 및 Map.Entry에 대한 팩토리 메소드가 있습니다.
Java SE 8 및 이전 버전에서는 unmodifiableXXX와 같은 Collections 클래스 유틸리티 메서드를 사용하여 Immutable Collection 개체를 만들 수 있습니다.
그러나 이러한 Collections.unmodifiableXXX 메서드는 매우 지루하고 장황한 접근 방식입니다. 이러한 단점을 극복하기 위해 Oracle corp는 List, Set 및 Map 인터페이스에 몇 가지 유틸리티 메서드를 추가했습니다.
이제 Java 9에서 :-List
및 Set 인터페이스에는 아래와 같이 비어 있거나 비어 있지 않은 Immutable List 또는 Set 객체를 만드는 “of ()”메서드가 있습니다.
빈 목록 예
List immutableList = List.of();
비어 있지 않은 목록 예
List immutableList = List.of("one","two","three");
답변
여기서 요점은 컬렉션이 수정할 수없는 경우에도 변경할 수 없다는 것을 보장하지 않는다는 것입니다. 예를 들어 너무 오래된 요소를 제거하는 컬렉션을 생각해보십시오. 수정할 수 없음은 참조를 보유한 객체가 변경할 수 없음을 의미하는 것이 아니라 변경할 수 없음을 의미합니다. 이것의 진정한 예는 Collections.unmodifiableList
방법입니다. 수정 불가능한 List 뷰를 반환합니다. 이 메서드에 전달 된 List 참조는 여전히 수정 가능하므로 전달 된 참조의 모든 소유자가 목록을 수정할 수 있습니다. 이로 인해 ConcurrentModificationExceptions 및 기타 나쁜 일이 발생할 수 있습니다.
불변이란 컬렉션을 변경할 수 없음을 의미합니다.
두 번째 질문 : 변경 불가능한 컬렉션은 컬렉션에 포함 된 개체가 변경되지 않는다는 의미가 아니라 해당 컬렉션이 보유하는 개체의 수와 구성이 변경되지 않을 것입니다. 즉, 컬렉션의 참조 목록은 변경되지 않습니다. 그렇다고 참조되는 개체의 내부가 변경 될 수 없다는 의미는 아닙니다.
답변
Pure4J 는 두 가지 방법으로 당신이 추구 하는 것을 지원합니다.
첫째, @ImmutableValue
주석을 제공 하므로 클래스에 주석을 달아 변경 불가능하다고 말할 수 있습니다. 코드가 실제로 변경 불가능한지 (사용 final
등) 확인할 수있는 maven 플러그인이 있습니다 .
둘째, Clojure의 영구 컬렉션 (제네릭이 추가됨)을 제공하고 컬렉션에 추가 된 요소가 변경되지 않도록합니다. 이것들의 성능은 분명히 꽤 좋습니다. 컬렉션은 모두 변경할 수 없지만 검사를 위해 Java 컬렉션 인터페이스 (및 제네릭)를 구현합니다. Mutation은 새 컬렉션을 반환합니다.
면책 조항 : 나는 이것의 개발자입니다
답변
