Guava Source Analysis--immutable Collections (4)

Source: Internet
Author: User

Immutable collection system, there is a very important collection is not introduced, is immutablemap, through the UML diagram, you can see IMMUTABLEMAP structure system.

First look at Immutablebimap, because the implementation of the ordinary immutablemap depends on it. Immutablebimap on the basis of Immutablemap, add inverse () and other methods, can make the key value reversal. The construction of Immutablebimap is also based on the number of elements, using different implementations (0-->emptyimmutablbimap,1-->singletonimmutablbimap,n (n>=2)-- REGULARIMMUBTALMAP), the code looks like this:

 Public Abstract classImmutablebimap<k, v>extendsImmutablemap<k, v>ImplementsBimap<k, v>{ Public Static<k, v> immutablebimap<k, v>of () {//inside the empty element, without maintaining the storage structure, the inverse () method directly returns this        return(Immutablebimap<k, v>) emptyimmutablebimap.instance; }     Public Static<k, v> immutablebimap<k, v>of (K K1, V v1) {//when a single element is constructed, returns this class, internally maintaining two elements K,v,inverse (), returning the V,k singletonimmutablebimap        return NewSingletonimmutablebimap<k, v>(K1, v1); }         Public Static<k, v> immutablebimap<k, v>of (k K1, v v1, K K2, v v2) {//multiple element constructs are, return this class, internally maintain two entry[] collections, a position with key as the Hashbucket,
Another position with value as hashbucket, used for inverse (), the reversal of Key-value return NewRegularimmutablebimap<k, v>(entryof (K1, v1), entryof (K2, v2)); }}

The CopyOf () method, implemented in Immutablecollections, is that if copyOf () is still a Immutablecollections collection, then only the assignment of the reference is made, because the collection itself is immutable.

After seeing Immutablebimap, looking back at Immutablemap is a lot simpler, just on immutablebimap basis except inverse () method, and inside for the user single array (hashbucket)

There is no need to maintain a reversed array. Call the Immutablebimap.of () and Immutablebimap.of (K,V) methods directly in the absence of elements and the construction of a single element, as shown in the following code:

 Public Abstract classImmutablemap<k, v>ImplementsMap<k, v>, Serializable {/*** Returns the empty map. This map behaves and performs comparably to * {@linkCollections#emptymap}, and is preferable mainly for consistency * and maintainability of your code. */   Public Static<k, v> immutablemap<k, v>of () {returnImmutablebimap.of (); }  /*** Returns An immutable map containing a single entry. This map behaves and * performs comparably to {@linkCollections#singletonmap} but would not accept * a null key or value.   It is preferable mainly for consistency and * maintainability of your code. */   Public Static<k, v> immutablemap<k, v>of (K K1, V v1) {returnimmutablebimap.of (K1, v1); }}

When multiple elements are constructed, the return regularimmubtalmap is similar to the internal implementation of REGULARIMMUTABLEBIMAP, removing the maintenance of the inverse (value-key) array, and removing the inverse () method.

Finally, the simple elaboration of the implementation of the Immutablesortedmap, Immutablemap single elements and the implementation of empty elements, it is not detailed to say that interested readers can see for themselves. When multiple elements are implemented,

Immutablesortedmap implementation class is Regularimmutablesortedmap, interestingly, its internal maintenance key and value of the data structure is two list, so imagine, the sort of early in the construction of the time has been completed, And the fact is, the exact code looks like this:

@SuppressWarnings ("Unchecked"publicstaticextendsSuperof (K K1, V V1, K K2, v v2, K K3, v v3, K K4, v v4) {       // the sequencer and entires incoming fromentries method       return
   
    false, 4
    , entryof (K1, v1), entryof (K2, V2), entryof (K3,                v3), entryof (K4, v4));}
   
  Static<k, v> immutablesortedmap<k, v>fromentries (Comparator<?SuperK> Comparator,BooleanSamecomparator,intSize, entry<k, v>... entries) {         for(inti = 0; i < size; i++) {Entry<k, v> entry =Entries[i]; Entries[i]=entryof (Entry.getkey (), Entry.getvalue ()); }        if(!samecomparator) {sortentries (comparator, size, entries);//Traversing entries sortingvalidateentries (size, entries, comparator); }        returnfromsortedentries (Comparator, size, entries); }
Static<k, v> immutablesortedmap<k, v>fromsortedentries (Comparator<?SuperK>Comparator,intSize,entry<k, v>[] entries) {        if(Size = = 0) {            returnEmptymap (Comparator); }        //iterate through the sorted entries, separating key and value, respectively, to form the respective listImmutablelist.builder<k> Keybuilder =Immutablelist.builder (); Immutablelist.builder<V> Valuebuilder =Immutablelist.builder ();  for(inti = 0; i < size; i++) {Entry<k, v> entry =Entries[i];            Keybuilder.add (Entry.getkey ());        Valuebuilder.add (Entry.getvalue ()); }        return NewRegularimmutablesortedmap<k, v>(                NewRegularimmutablesortedset<k>(Keybuilder.build (), comparator), Valuebuilder.build ());}

The entry in Immutablemap is also being re-implemented by guava, adding a bucket of computational logic, such as UML:

Abstractmapentry on the basis of the original map.entry, write operation, set as the direct throw anomaly, Immutableentry realize Getkey () and GetValue (), Immutablemapentry the calculation and maintenance methods of the buckets (linked list), which are finally reflected to nonterminalmapentry and terminalentry, for these two classes, Terminalentry is the tail node of the bucket list, so it is implemented as follows:

Static Final classTerminalentry<k, v>extendsImmutablemapentry<k, v>{terminalentry (immutablemapentry<k, v>contents) {            Super(contents); } terminalentry (K key, V value) {Super(key, value); } @Override @Nullable Immutablemapentry<k, v>Getnextinkeybucket () {//tail node, so no Nuext            return NULL; } @Override @Nullable Immutablemapentry<k, v>Getnextinvaluebucket () {//tail node, so no Nuext            return NULL; }    }

The nonterminalmapentry structure is required to pass in the next entry

Private Static Final classNonterminalmapentry<k, v>extendsImmutablemapentry<k, v> {    Private FinalImmutablemapentry<k, v>Nextinkeybucket; Nonterminalmapentry (K key, V value, Immutablemapentry<k, v>nextinkeybucket) {      Super(key, value);  This. Nextinkeybucket =Nextinkeybucket; } nonterminalmapentry (Immutablemapentry<k, v> contents, immutablemapentry<k, v>nextinkeybucket) {      Super(contents);  This. Nextinkeybucket =Nextinkeybucket; } @Override immutablemapentry<k, v>Getnextinkeybucket () {//the next entry in the same bucket      returnNextinkeybucket; } @Override @Nullable Immutablemapentry<k, v>Getnextinvaluebucket () {//Bimap will maintain value buckets.      return NULL; }  }

Then, in the construction, if a hash conflict occurs, it is with Nonterminalmapentry, the code is as follows:

Regularimmutablemap (entry<?,? >[] theentries) {    intSize =theentries.length; Entries=Createentryarray (size); intTablesize =hashing.closedtablesize (size, max_load_factor); Table=Createentryarray (tablesize); Mask= TableSize-1;  for(intEntryindex = 0; Entryindex < size; entryindex++) {@SuppressWarnings ("Unchecked")//All we callers carefully put in only entry<k, V>sEntry<k, v> Entry = (entry<k, v>) Theentries[entryindex]; K Key=Entry.getkey (); V value=Entry.getvalue ();      Checkentrynotnull (key, value); intTableindex = Hashing.smear (Key.hashcode ()) &Mask; @Nullable Immutablemapentry<k, v> existing =Table[tableindex]; //prepend, not append, so the entries can be immutable//in the construction is, if a hash conflict arises, then the direct append to the front of the terminalImmutablemapentry<k, v> newEntry = (existing = =NULL)          ?NewTerminalentry<k, v>(key, value):NewNonterminalmapentry<k, v>(key, value, existing); Table[tableindex]=NewEntry; Entries[entryindex]=NewEntry;    Checknoconflictinbucket (Key, newEntry, existing); }  }

Guava Source Analysis--immutable Collections (4)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.