Immutable collection, as the name implies, means that the collection cannot be modified. The data items of a collection are provided at the time of creation and cannot be changed throughout the life cycle.
Why use immutable objects? Immutable objects have the following advantages:
1. It is safe to use for unreliable client code libraries, and these objects can be used safely in untrusted class libraries
2 .Thread-safe: immutable objects are safe under multi-threading and have no race conditions
3. There is no need to support variability, and you can try to save space and time overhead. All immutable collection implementations are better than mutable collections Collections use memory more efficiently (analysis)
4. Can be used as a constant and are expected to remain unchanged in the future
Immutable objects can be used as constants naturally because They are inherently immutable. It is a good defensive programming technique to use immutable objects.
Implementation of immutable collections in JDK
Collections.unmodifiableXXX series of methods are provided in JDK to implement immutable collections, but there are some problems. Let’s look at a specific example first:
[code]import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; public class ImmutableTest { @Test public void testJDKImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println(list); List<String> unmodifiableList=Collections.unmodifiableList(list); System.out.println(unmodifiableList); List<String> unmodifiableList1=Collections.unmodifiableList(Arrays.asList("a","b","c")); System.out.println(unmodifiableList1); String temp=unmodifiableList.get(1); System.out.println("unmodifiableList [0]:"+temp); list.add("baby"); System.out.println("list add a item after list:"+list); System.out.println("list add a item after unmodifiableList:"+unmodifiableList); unmodifiableList1.add("bb"); System.out.println("unmodifiableList add a item after list:"+unmodifiableList1); unmodifiableList.add("cc"); System.out.println("unmodifiableList add a item after list:"+unmodifiableList); } }
[code][a, b, c] [a, b, c] [a, b, c] unmodifiableList [0]:b list add a item after list:[a, b, c, baby] list add a item after unmodifiableList1:[a, b, c, baby]
1. It’s clumsy and cumbersome to use. You have to use this method in every defensive programming copy place.
2. It’s unsafe: if there is an object referencing the original For encapsulated collection classes, the collections returned by these methods are not truly immutable.
3. Low efficiency: Because the essence of the data structure it returns is still the original collection class, its operation overhead, including concurrent modification checking, and the extra data space in the hash table are the same as the original collection. the same.
Guava’s immutable collection
Guava provides a simple and convenient implementation of the immutable version of the standard collection classes in the JDK, as well as Guava’s own immutable implementations of some specialized collection classes. When you do not want to modify a collection class, or want to make a constant collection class, using an immutable collection class is a best programming practice.
Note: Every implementation of Guava immutable collection classes rejects null values. We did a comprehensive investigation of Google's internal code and found that collection classes allow null values in only 5% of the cases, while rejecting null values in 95% of the cases. In case you really need a collection class that can accept null values, you might consider using Collections.unmodifiableXXX.
How to use Immutable collections:
An immutable collection can be created in the following ways:
1. Use the copyOf method, for example, ImmutableSet.copyOf(set)
2. Use the of method, for example, ImmutableSet.of("a", "b", "c") or ImmutableMap.of("a", 1, "b", 2)
3. Use the Builder class
[code]@Test public void testGuavaImmutable(){ List<String> list=new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); System.out.println("list:"+list); ImmutableList<String> imlist=ImmutableList.copyOf(list); System.out.println("imlist:"+imlist); ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry"); System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b"); System.out.println("imSortList:"+imSortList); list.add("baby"); System.out.println("list add a item after list:"+list); System.out.println("list add a item after imlist:"+imlist); ImmutableSet<Color> imColorSet = ImmutableSet.<Color>builder() .add(new Color(0, 255, 255)) .add(new Color(0, 191, 255)) .build(); System.out.println("imColorSet:"+imColorSet); }
"b", "c", "a", "d", "b"), the traversal order of this collection is "a", "b" ", "c", "d".
Smarter copyOf
The copyOf method is smarter than you think. ImmutableXXX.copyOf will avoid copying elements under appropriate circumstances - ignore the specific details first, but its implementation They are generally very "intelligent". For example
[code]@Test public void testCotyOf(){ ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa"); System.out.println("imSet:"+imSet); ImmutableList<String> imlist=ImmutableList.copyOf(imSet); System.out.println("imlist:"+imlist); ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet); System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>(); for(int i=0;i<20;i++){ list.add(i+"x"); } System.out.println("list:"+list); ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 18)); System.out.println("imInfolist:"+imInfolist); int imInfolistSize=imInfolist.size(); System.out.println("imInfolistSize:"+imInfolistSize); ImmutableSet<String> imInfoSet=ImmutableSet.copyOf(imInfolist.subList(2, imInfolistSize-3)); System.out.println("imInfoSet:"+imInfoSet); }
[code]imSet:[peida, jerry, harry, lisa] imlist:[peida, jerry, harry, lisa] imSortSet:[harry, jerry, lisa, peida] list:[0x, 1x, 2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x, 18x, 19x] imInfolist:[2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x] imInfolistSize:16 imInfoSet:[4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x]
In this code, ImmutableList.copyOf(imSet) will intelligently return imSet.asList() of ImmutableSet with constant time complexity.
Generally speaking, ImmutableXXX.copyOf(ImmutableCollection) will avoid linear complexity copy operations. For example, in the following situations:
This operation may take advantage of the constant complexity operation of the encapsulated data structure. But for example ImmutableSet.copyOf(list) cannot be implemented with constant complexity.
This will not cause memory leaks - for example, you have an ImmutableList imInfolist, and then you explicitly operate ImmutableList.copyOf(imInfolist.subList(0, 10)). This operation avoids accidentally holding a reference to an element in the hugeList that is no longer needed.
It does not change the semantics of the set - explicit copy operations like ImmutableSet.copyOf(myImmutableSortedSet), because the meaning of hashCode() and equals() in ImmutableSet is different from the comparator-based ImmutableSortedSet. .
These features help optimize the performance overhead of defensive programming.
asList method
All immutable collections provide ImmutableList views in the form of asList(). For example, if you put the data in ImmutableSortedSet, you can call sortedSet.asList().get(k) to get the set of the first k elements.
The returned ImmutableList is often a constant complexity view rather than a true copy. In other words, this returned collection is smarter than a normal List - for example, it will implement methods like contains more efficiently.
[code] @Test public void testAsList(){ ImmutableList<String> imList=ImmutableList.of("peida","jerry","harry","lisa","jerry"); System.out.println("imList:"+imList); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.copyOf(imList); System.out.println("imSortList:"+imSortList); System.out.println("imSortList as list:"+imSortList.asList()); }
[code]imList:[peida, jerry, harry, lisa, jerry] imSortList:[harry, jerry, lisa, peida] imSortList as list:[harry, jerry, lisa, peida]
Guava集合和不可变对应关系
可变集合类型 可变集合源:JDK or Guava? Guava不可变集合
Collection JDK ImmutableCollection
List JDK ImmutableList
Set JDK ImmutableSet
SortedSet/NavigableSet JDK ImmutableSortedSet
Map JDK ImmutableMap
SortedMap JDK ImmutableSortedMap
Multiset Guava ImmutableMultiset
SortedMultiset Guava ImmutableSortedMultiset
Multimap Guava ImmutableMultimap
ListMultimap Guava ImmutableListMultimap
SetMultimap Guava ImmutableSetMultimap
BiMap Guava ImmutableBiMap
ClassToInstanceMap Guava ImmutableClassToInstanceMap
Table Guava ImmutableTable
以上就是Java-类库-Guava-Immutable(不可变)集合的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!