Java HashMap is the use of a very high frequency of a class, often encountered in the work of traversing HashMap scene, then how to effectively traverse HashMap? First analyze the HASHMAP storage structure from the source code:
1 transient entry<k,v>[] table = (entry<k,v>[]) empty_table;
It can be seen that the actual stored structure is a entry array, the general traversal HashMap mainly have two methods, by obtaining the map entry set or key set iterator to traverse. Still analyze from the source code, see how HashMap's entry set and key set are implemented.
1. Implementation of the Entry Set
1 Private transientSet<map.entry<k,v>> EntrySet =NULL;2 3 Private Final classEntrySetextendsAbstractset<map.entry<k, v>> {4 PublicIterator<map.entry<k, v>>iterator () {5 returnnewentryiterator ();6 }7 8 Public Booleancontains (Object o) {9 if(! (Oinstanceofmap.entry)) {Ten return false; One } A -Map.entry<k, v> e = (map.entry<k, v>) O; -Entry<k, v> candidate =Getentry (E.getkey ()); the - return(Candidate! =NULL) &&candidate.equals (e); - } - + Public BooleanRemove (Object o) { - returnRemovemapping (o)! =NULL; + } A at Public intsize () { - returnsize; - } - - Public voidClear () { -HashMap. This. Clear (); in } -}
As can be seen from the above code, if you need to traverse entry set, only through iterator traversal, look at the Newentryiterator () method call path
1Iterator<map.entry<k,v>>Newentryiterator () {2 return Newentryiterator ();3 }4 5 Private Final classEntryiteratorextendsHashiterator<map.entry<k, v>> {6 PublicMap.entry<k, v>Next () {7 returnnextentry ();8 }9 }Ten One FinalEntry<k,v>NextEntry () { A if(Modcount! =expectedmodcount) - Throw Newconcurrentmodificationexception (); -Entry<k,v> e =Next; the if(E = =NULL) - Throw Newnosuchelementexception (); - - if(next = e.next) = =NULL) { +entry[] t =table; - while(Index < T.length && (next = t[index++]) = =NULL); + } ACurrent =e; at returne; -}
As can be seen from the NextEntry () method, traversing through the entry set method is actually a traversal of the entry array, and HASHMAP does not save a entry set separately.
2. Implementation of Key Set
Also through the source analysis key set
1 transient volatileSet<k> KeySet =NULL;//from Abstractmap2 3 Private Final classKeySetextendsAbstractset<k> {4 PublicIterator<k>iterator () {5 returnnewkeyiterator ();6 }7 8 Public intsize () {9 returnsize;Ten } One A Public Booleancontains (Object o) { - returnContainsKey (o); - } the - Public BooleanRemove (Object o) { - returnHashMap. This. Removeentryforkey (o)! =NULL; - } + - Public voidClear () { +HashMap. This. Clear (); A } at } - -Iterator<k>Newkeyiterator () { - return Newkeyiterator (); - } - in Private Final classKeyiteratorextendsHashiterator<k> { - PublicK Next () { to returnnextentry (). GetKey (); + } -}
The way to traverse the key set is actually done by traversing the entry set, and then obtaining the entry key, so if you traverse the HASHMAP through key set, the entry set method will be more than the hashmap.get () to get Value This step, verify the conjecture by testing the code below.
1 ImportJava.util.Calendar;2 ImportJava.util.HashMap;3 ImportJava.util.Map;4 5 Public classTesthashmap {6 7 Public Static voidTraverse_hash_map (inttype) {8Hashmap<integer, integer> map =NewHashMap ();9 intSize = 10000000;Ten for(inti = 0; i < size; ++i) { One Map.put (i, i); A } - - DoubleStart =calendar.getinstance (). Gettimeinmillis (); the if(0 = =type) { - traverse_hash_map_by_entry_set (map); -System.out.println ("by Entry set:"); -}Else { + traverse_hash_map_by_key_set (map); -System.out.println ("by Key set:"); + } ASystem.out.println (Calendar.getinstance (). Gettimeinmillis ()-start); at } - - Private Static voidTraverse_hash_map_by_entry_set (Hashmap<integer, integer>map) { - for(Map.entry<integer, integer>Entry:map.entrySet ()) { - intKey =Entry.getkey (); - intValue =Entry.getvalue (); in } - } to + Private Static voidTraverse_hash_map_by_key_set (Hashmap<integer, integer>map) { - for(Integer key:map.keySet ()) { the intValue =Map.get (key); * } $ }Panax Notoginseng - Public Static voidMain (string[] args) { theTraverse_hash_map (0); +Traverse_hash_map (1); A } the}
The test results are:
12 112.034 129.0
The order of the exchange tests, the result is:
12 157.034 95.0
The above test shows that for HASHMAP traversal, the efficiency of entry set is higher than the traversal of key set, the whole HashMap should be traversed using entry set iterator method as far as possible.
The way of HASHMAP traversal