변경 불가능한 컬렉션과 수정 불가능한 컬렉션
보내는 사람 컬렉션 프레임 워크 개요 :
수정 작업을 지원하지 않는 컬렉션은 (예컨대
add,remove및clear)라고도 불가능한 . 수정할 수 없는 컬렉션은 수정할 수 있습니다.
Collection객체의 변화가 보이지 않도록 추가로 보장하는 컬렉션은 불변 이라고합니다 . 변경할 수없는 컬렉션은 변경 가능 합니다.
구별을 이해할 수 없습니다. 여기서 수정 불가능 과 불변
의 차이점은 무엇입니까 ?
수정 불가능한 콜렉션은 종종 다른 코드가 여전히 액세스 할 수 있는 수정 가능한 콜렉션의 랩퍼 입니다. 그래서 동안 당신은 당신 만 변경 불가능한 컬렉션에 대한 참조가있는 경우이를 변경할 수 없습니다, 당신은 변경하지 않는 내용에 의존 할 수 없다.
불변 수집 보장하는 것이 아무것도 더 이상 컬렉션을 변경할 수 있습니다. 수정 가능한 컬렉션을 래핑하는 경우 다른 코드가 해당 수정 가능한 컬렉션에 액세스 할 수 없도록합니다. 코드가 컬렉션에 참조를 포함하는 개체를 변경할 수는 없지만 개체 자체는 여전히 변경 가능할 수 있습니다. 불변의 컬렉션을 만들면 StringBuilder해당 개체가 "고정"되지 않습니다.
기본적으로 차이점은 다른 코드가 컬렉션 뒤에서 컬렉션을 변경할 수 있는지 여부입니다.
기본적으로 unModifiableCollection은 뷰이므로 간접적으로 수정 가능한 다른 참조에서 여전히 '수정'될 수 있습니다. 또한 다른 콜렉션 의 읽기 전용보기 로서 소스 콜렉션이 변경 될 때 수정 불가능한 콜렉션은 항상 최신 값으로 표시됩니다.
그러나 immutable콜렉션 은 다른 콜렉션 의 읽기 전용 사본 으로 취급 될 수 있으며 수정할 수 없습니다. 이 경우 소스 콜렉션이 변경되면 변경 불가능한 콜렉션은 변경 사항을 반영하지 않습니다.
다음은 이러한 차이를 시각화하는 테스트 사례입니다.
@Test
public void testList() {
List<String> modifiableList = new ArrayList<String>();
modifiableList.add("a");
System.out.println("modifiableList:"+modifiableList);
System.out.println("--");
//unModifiableList
assertEquals(1, modifiableList.size());
List<String> unModifiableList=Collections.unmodifiableList(
modifiableList);
modifiableList.add("b");
boolean exceptionThrown=false;
try {
unModifiableList.add("b");
fail("add supported for unModifiableList!!");
} catch (UnsupportedOperationException e) {
exceptionThrown=true;
System.out.println("unModifiableList.add() not supported");
}
assertTrue(exceptionThrown);
System.out.println("modifiableList:"+modifiableList);
System.out.println("unModifiableList:"+unModifiableList);
assertEquals(2, modifiableList.size());
assertEquals(2, unModifiableList.size());
System.out.println("--");
//immutableList
List<String> immutableList=Collections.unmodifiableList(
new ArrayList<String>(modifiableList));
modifiableList.add("c");
exceptionThrown=false;
try {
immutableList.add("c");
fail("add supported for immutableList!!");
} catch (UnsupportedOperationException e) {
exceptionThrown=true;
System.out.println("immutableList.add() not supported");
}
assertTrue(exceptionThrown);
System.out.println("modifiableList:"+modifiableList);
System.out.println("unModifiableList:"+unModifiableList);
System.out.println("immutableList:"+immutableList);
System.out.println("--");
assertEquals(3, modifiableList.size());
assertEquals(3, unModifiableList.size());
assertEquals(2, immutableList.size());
}
산출
modifiableList:[a]
--
unModifiableList.add() not supported
modifiableList:[a, b]
unModifiableList:[a, b]
--
immutableList.add() not supported
modifiableList:[a, b, c]
unModifiableList:[a, b, c]
immutableList:[a, b]
--
I think the main difference is that the owner of a mutable collection might want to provide access to the collection to some other code, but provide that access through an interface that doens't allow the other code to modify the collection (while reserving that capability to the owning code). So the collection isn't immutable, but certain users aren't permitted to change the collection.
Oracle's Java Collection Wrapper tutorial has this to say (emphasis added):
Unmodifiable wrappers have two main uses, as follows:
- To make a collection immutable once it has been built. In this case, it's good practice not to maintain a reference to the backing collection. This absolutely guarantees immutability.
- To allow certain clients read-only access to your data structures. You keep a reference to the backing collection but hand out a reference to the wrapper. In this way, clients can look but not modify, while you maintain full access.
If we are talking about JDK Unmodifiable* vs guava Immutable*, actually the difference is also in performance. Immutable collections can be both faster and more memory-efficient if they are not wrappers around regular collections (JDK implementations are wrappers). Citing the guava team:
The JDK provides Collections.unmodifiableXXX methods, but in our opinion, these can be
<...>
- inefficient: the data structures still have all the overhead of mutable collections, including concurrent modification checks, extra space in hash tables, etc.
To quote The Java™ Tutorials:
Unlike synchronization wrappers, which add functionality to the wrapped collection, the unmodifiable wrappers take functionality away. In particular, they take away the ability to modify the collection by intercepting all the operations that would modify the collection and throwing an UnsupportedOperationException. Unmodifiable wrappers have two main uses, as follows:
To make a collection immutable once it has been built. In this case, it's good practice not to maintain a reference to the backing collection. This absolutely guarantees immutability.
To allow certain clients read-only access to your data structures. You keep a reference to the backing collection but hand out a reference to the wrapper. In this way, clients can look but not modify, while you maintain full access.
(emphasis mine)
This really sums it up.
As noted above unmodifiable is not like immutable because an unmodifiable collection can be altered if for example an unmodifiable collection has an underlying delegate collection which is referenced by some other object and that object changes it.
Regarding immutable, it's not even well defined. However, generally it means that the object "will not change", but that would need to be defined recursively. For example, I can define immutable on classes whose instance variables are all primitives and whose methods all contain no arguments and return primitives. The methods then recursively allow the instance variables to be immutable and all methods to contain arguments that are immutable and that return immutable values. The methods should be guaranteed to return the same value over time.
Assuming that we can do that, there is also the concept thread safe. And you might be led to believe that immutable (or not changeble over time) also implies thread safe. However that is not the case and that is the main point I am making here that has not yet been noted in other answers. I can construct an immutable object that always returns the same results yet is not thread safe. To see this suppose that I construct an immutable collection by maintaining additions and deletions over time. Now the immutable collection returns its elements by looking at the internal collection (which may be changing over time) and then (internally) adding and deleting the elements that were added or deleted after creation of the collection. Clearly, although the collection would always return the same elements, it is not thread safe merely because it will never change value.
Now we can define immutable as objects that are thread safe and will never change. There are guidelines for creating immutable classes that generally lead to such classes, however, keep in mind that there may be ways to create immutable classes, that require attention to thread safety, for example, as described in the "snapshot" collection example above.
참고URL : https://stackoverflow.com/questions/8892350/immutable-vs-unmodifiable-collection
'Programming' 카테고리의 다른 글
| Chrome의 Greasemonkey 스크립트에서 jQuery를 사용하려면 어떻게해야하나요? (0) | 2020.06.07 |
|---|---|
| 시간 또는 10 분 단위로 시간을 그룹화하는 방법 (0) | 2020.06.07 |
| CultureInfo.InvariantCulture은 무슨 뜻인가요? (0) | 2020.06.07 |
| Java 스위치 명령문 : 상수 표현식이 필요하지만 상수입니다. (0) | 2020.06.07 |
| 로컬 컴퓨터에서 원격 DB를 mysqldump하는 방법 (0) | 2020.06.07 |