Immutable collections, as the name implies, is that a collection cannot be modified. The data items of the collection are provided at the time of creation and are immutable throughout the life cycle.
Why do you use immutable objects? The immutable object has the following advantages:
1. For unreliable customer code libraries, it is safe to use these objects securely in untrusted class libraries
2. Thread-Safe: Immutable objects are safe under multiple threads, no race condition
3. There is no need to support variability, you can save space and time overhead. All immutable collection implementations are more efficient at using memory than mutable collections (analysis)
4. Can be used as a constant, and expect to remain unchanged in the future
Immutable objects can be used naturally as constants because they are inherently immutable, and it is a good technical practice for defense programming (defensive programming) for the use of immutable objects.
Implement immutable collection in JDK
Collections.unmodifiablexxx series methods are provided in the JDK to implement immutable collections, but there are some problems, let's look at a specific example:
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"); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;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); }}
Output:
[A, B, c] [A, B, c] [A, B, c]unmodifiablelist [0]:blist Add a item after list:[a, B, C, baby]list add a item after unmodifiablelist1:[a, B, C, Baby
Description: The collections.unmodifiablelist implementation is not a true immutable collection, and the immutable collection changes when the original collection is modified. Immutable collections can not modify the collection data, when forced modification will be an error, the last two instances of add will directly throw a non-modifiable error.
Summarize some of the problems with the Collections.unmodifiablexxx method of the JDK to implement immutable collections:
1. It's clumsy and cumbersome you have to use this method in every defensive programming copy.
2. It is unsafe: if there are objects reference the original encapsulated collection class, the collection returned by these methods is not really immutable.
3. Inefficient: Because the nature of the data structure it returns is still the original collection class, its operating overhead, including the concurrent modification check, the hash table in the additional data space is the same as the original collection.
Immutable collection of Guava
Guava provides a simple and convenient implementation of the immutable version of the standard collection class in the JDK, as well as the immutable implementation of some of Guava's own specialized collection classes. Using the Immutable collection class is one of the best programming practices when you don't want to modify a collection class, or want to make a constant collection class.
Note: The implementation of each guava immutable collection class rejects the null value. We did a full survey of Google's internal code, and found that only 5% of the collection classes allowed null values, while 95% rejected null values. In case you really need a collection class that can accept null values, you can consider using COLLECTIONS.UNMODIFIABLEXXX.
Immutable how to use the collection:
A immutable collection can be created in the following ways:
1. Using the CopyOf method, for example, immutableset.copyof (set)
2. Using the of method, for example, Immutableset.of ("A", "B", "C") or Immutablemap.of ("a", 1, "B", 2)
3. Using the Builder class
Instance:
@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); }
Output:
List:[a, B, C]imlist:[a, B, C]imoflist:[peida, Jerry, Harry]imsortlist:[a, B, C, d]list add a item after list:[a, B, C, BA By]list add a item after imlist:[a, B, c]imcolorset:[java.awt.color[r=0,g=255,b=255], java.awt.color[r=0,g=191,b=255]
There is an exception to the sorted collection, because the order of the elements is fixed when the collection is built. For example, Immutableset.of ("A", "B", "C", "a", "D", "B") are "a", "B", "C", "D" for this set's traversal order.
More Intelligent copyof
The Copyof method is smarter than you think, and immutablexxx.copyof avoids copying the elements in the right circumstances-ignoring the specifics, but its implementation is generally "smart". Such as:
@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); }
Output:
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, 19x]iminfolist:[2x, 16x, 17x, 18x, 3x, 4x, 5x, 6x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x]iminfolistsize:16iminfoset:[4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x
In this code, immutablelist.copyof (Imset) intelligently returns Imset.aslist () of immutableset with a constant time complexity.
In general, immutablexxx.copyof (immutablecollection) avoids copying operations with linear complexity. As in the following situations:
This operation is likely to take advantage of the constant complexity of the encapsulated data structure. However, for example, immutableset.copyof (list) cannot be implemented in constant complexity.
This does not cause a memory leak-for example, you have a immutablelist<string> iminfolist, and then you explicitly manipulate immutablelist.copyof (iminfolist.sublist (0, 10)). Such an operation avoids accidentally holding reference of elements that are no longer needed in hugelist.
It does not change the semantics of the set-explicit copy operations like Immutableset.copyof (Myimmutablesortedset), because Hashcode () and Equals () in Immutableset The meaning and the immutablesortedset based on comparator are different.
These features help optimize the performance overhead of defensive programming.
Aslist method
All immutable collections provide immutablelist views (view) in the form of aslist (). For example, if you put the data in Immutablesortedset, you can call Sortedset.aslist (). Get (k) to get a collection of the first k elements.
The returned immutablelist is often a view of constant complexity rather than a true copy. In other words, this return collection is smarter than the general list-for example, it would be more efficient to implement a method like contains.
Instance:
@Test public void Testaslist () {immutablelist<string> imlist=immutablelist.of ("Peida", "Jerry", "Harry", "Lis A "," 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 ()); }
Output:
Imlist:[peida, Jerry, Harry, Lisa, Jerry]imsortlist:[harry, Jerry, Lisa, Peida]imsortlist as List:[harry, Jerry, Lisa, Pei Da
Guava set and immutable correspondence relation
Variable collection type |
mutable collection Source: JDK or Guava? |
Guava Immutable Collection |
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 |
Immutablexxx can only do to the collection corresponding to the non-editable, the object in the collection is not really copied, if the internal objects are modified, or will be chained to take effect, such as the following code will output 100. Vice versa.
JavaBean bean= New JavaBean (0); List<javabean > List = new Arraylist<javabean > (); List.add (Bean); Immutablelist<javabean > copyOf = immutablelist.copyof (list); JavaBean bean2 = copyof.get (0); Bean.setid (100); System.out.println (Bean2.getid ());
Guava Study notes: Immutable (immutable) collection