Note: when reading this article and related source code, need data structure related knowledge, including: Hash table, linked list, red black tree.
A map is an object that maps a key (key) to a value. Different mappings cannot contain the same key, and each key can be mapped to at most one value. is the interface and implementation of common maps. Compared with collection, the inheritance relationship is quite simple.
first, map interface and Abstractmap abstract class
The map interface, in addition to adding mappings, obtaining value based on key, determining whether a key or value in a map exists, or deleting a mapping, contains a method that returns a set containing all keys and a collection containing all of the value. Since key cannot be duplicated, the returned collection naturally has the Set property and is well suited to return with set. and value is not.
Unlike other collection interfaces, there is a sub-interface in the map interface: Entry. Entry represents a mapping that contains both the key and value parts, while a enry key does not provide a modification method, and value allows for modification. It is necessary to note that if a mutable object is used as the key of the map, the behavior of the map is indeterminate (JDK1.6 document) If the change Equals () is different from the previous behavior.
For abstract class Abstractmap, most of the implemented methods are based on the abstract method returned by the set of all Entry EntrySet (): Size (), IsEmpty () (using size ()), Containsvalue (), ContainsKey (), get (), clear (), KeySet (), values (), and so on. Remove (), RemoveAll (), Retainall (), clear (), and toString () use the abstract method iterator ().
The values () return value is a abstractcollection of an anonymous inner class implementation. Value is created on first access and is returned in all subsequent accesses. Although the element is not synchronized, its reference is almost always constant, but the behavior of the return value changes with the elements in the map:
PublicCollection<v>values () {if(Values = =NULL) {Values=NewAbstractcollection<v>() { PublicIterator<v>iterator () {return NewIterator<v>() {Privateiterator<entry<k,v>> i =EntrySet (). iterator (); Public BooleanHasnext () {returnI.hasnext (); } PublicV Next () {returnI.next (). GetValue (); } Public voidRemove () {i.remove (); } }; } Public intsize () {returnAbstractmap. This. Size (); } Public Booleancontains (Object v) {returnAbstractmap. This. Containsvalue (v); } }; } returnvalues;}
For Map.entry,abstractmap, two key-value pair types are implemented: Simpleentry and Simpleimmutableentry. The difference between the latter and the former is that SetValue () is not allowed, and calling the method throws a Unsupportedoperationexception exception.
Second, Hashmap/linkedhashmap/weakhashmap
In the beginning of Java (iv): The carding of the container relationship (above)--collection the bottom of the hashset/linkedhashset is actually hashmap/linkedhashmap. HashMap is the same as the general hash list implementation, with the array of elements that hold the same hash value as the first element of the queue, the element of the queue is entry, including the key, value, hash value, next and other attributes. When looking for a specified key, hash the corresponding queue header in the array based on the hash value, and traverse the queue to find the key and the corresponding value.
Since HASHMAP allows NULL as key, the key does not calculate the hash value, only the array of hashes is traversed, and the first element's key is found to be a null queue. This implementation can refer to the private Method Getfornullkey ().
The hash value array for the HASHMAP key has a capacity limit: must be a power of 2. Even if you specify a capacity of a power of not 2 at the time of new HashMap or when you call resize (), the actual call to the newly hashmap capacity will also expand to a value not less than the power of 2 of this specified capacity. Associated with it, the hash value of the calculation hash () and a hash value in the index of the array are computed indexfor () in the following way:
static int hash (int h) { // This function ensures so hashcodes that differ only by // constant multiples at each bit position has a bounded // number of collisions (approximately 8 at default load factor). H ^= (H >>>) ^ (H >>> 12); return H ^ (H >>> 7) ^ (H >>> 4);}
Static int indexfor (intint length) { return H & (Length-1);}
A power of 2 guarantees proper truncation (discarding high) when the index is computed.
The relationship between Linkedhashmap and HashMap is not the same as LinkedList and ArrayList. Structurally, Linkedhashmap simply makes all the entry a doubly linked list. This allows you to access all the elements (by setting the accessorder tag bit) in either the insertion order or the LRU sequence while iterating through the iteration.
Weakhashmap and HashMap are similar in that they contain a referencequeue, and its entry is inherited from WeakReference. In this way, when clear (), resize (), size (), getTable () are called, the Expungestaleentries () method is invoked, and the mappings that are no longer used are garbage collected. This is not a description of what reference is about.
Consider the question raised in the previous article: Is it possible to implement HashSet first and then implement HashMap with HashSet? Personally, this implementation of the HashSet element (corresponding to map entry), only the key has no value, is not directly implemented HashMap.
Second, hashtable/properties
Although Hashtable implemented the map interface, it did not use Abstractmap to do it. Its behavior is similar to HashMap, it is retained to be compatible with the original code, and is not recommended for continued use.
The properties that inherit the hashtable<object,object> are slightly different, and they are closely related to the flow, which can be saved in the stream or loaded from the stream. In addition, it is thread-safe.
Iii. SortedMap and TreeMap
All elements in the SortedMap are ordered. This "sort" is different from linkedhashmap all the elements into a single list, but refers to any of the two elements can compare the size of the relationship, and according to the comparison rule comparator order. To be more precise, it is the key size relationship. Built on an orderly basis, the SortedMap interface includes methods to return part of the map Submap (k Fromkey, K Tokey), Headmap (K tokey), Tailmap (K-Fromkey), and end-to-end key methods Firstkey (), Lastkey ().
TreeMap is an implementation of SortedMap, whose compartor can be null, in which case the element's own CompareTo () method is called when the element size is compared.
TreeMap actually used a red-black tree to preserve the root of the tree. About the red and black tree algorithm, speaking can open a separate article, here does not unfold, want to understand the reader can read the "Introduction to the algorithm" related chapters. The insertion and deletion of treemap elements is actually the insertion and deletion of red and black tree nodes. Finding a specific key (and the corresponding value) is also a way to find a red-black tree in order to find the element.
Introduction to Java (V): Carding of container relationships (--MAP)