That little thing about the map big family (1): Map

Source: Internet
Author: User
Tags comparable map data structure concurrentmodificationexception

Map is a data structure for fast lookup, it stores data in the form of key-value pairs, each key is unique, and corresponds to a value, if you want to find the data in the map, only need to pass in a key, map will match the key and return the value corresponding to the key, You can say that map is actually a collection of key-value pairs. Map is widely used in a variety of programming languages, except that it may be confusing in name, like a dictionary in Python (Dictionary), and some languages called associative arrays (associative array), but they are all the same and are a collection of key-value pairs. As for the common use of Java HashMap is also a map, it is known as a hash table, about the details of the hash table in this article I will explain the source of HashMap mentioned.

Java also provides a data structure that is closely related to map: set, which is a set of mathematical meanings, with the following characteristics:

Disorder: In a set, each element's status is the same, and the elements are unordered. But Java also provides an ordered set, which is not exactly followed.
Cross-specific: In a collection, any two elements are not the same.
Determinism: Given a collection and any of its elements, it must be determined that the element belongs to, or does not belong to, the collection.
Obviously, the key in the map conforms to these features, and the implementation of the set is actually using the map internally. For example, HashSet defines a member variable of type HashMap, adding element A to hashset, which is equivalent to adding a key value pair to the hashmap inside it that is a,value to an object. This object is a constant of hashset, it is a dummy value, there is no actual meaning, the source code is as follows:

private transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();public boolean add(E e) {    return map.put(e, PRESENT)==null;}

After the episode, let's go on to the map, which is a top-level interface to the JDK, and provides three collections views: A collection of all keys, a collection containing all the values, and a collection of all the key-value pairs, Collection. The order of elements in the map is related to the order of the elements in the collection view that it returns, that is, the map itself is not guaranteed to be ordered, and of course there are exceptions, such as TREEMAP, which guarantees ordering, mainly because it is based on red-black trees.

The so-called collection view is a way of accessing the data provided by the collection itself, and any modifications to the views also affect the collection. Like Map.keyset () returns the set of keys it contains, and if you call Map.Remove (key) then Keyset.contains (key) will also return false, say Arrays.aslist (T) You can encapsulate an array into a list so that you can access and manipulate the data through the list's API, such as the following sample code:

String[] strings = {"a", "b", "c"};List<String> list = Arrays.asList(strings);System.out.println(list.get(0)); // "a"strings[0] = "d";System.out.println(list.get(0)); // "d"list.set(0, "e");System.out.println(strings[0]); // "e"

Does it feel magical, in fact arrays.aslist () just passing in an array with an inner class in arrays ArrayList (note that it is not the same as ArrayList under the Java.util package) does a "bind" in the call Get () The elements in the array are returned directly according to the subscript, and when the set () is called, the corresponding subscript element in the array is also modified directly. In the case of direct replication, the advantage of a collection view is that memory utilization is higher, assuming you have an array and want to use the list API to manipulate it, then you do not need to new a ArrayList to copy the elements in the array. With only a little extra memory (encapsulated by Arrays.arraylist Array), the original data remains in the array and is not copied into multiple copies.

The map interface regulates the generic API for the map data structure (and also contains several default methods for simplifying operations, default is the new feature of JDK8, which is the defaults implementation of methods declared in the interface, i.e. non-abstract methods) and also internally defines the entry interface (the entity class for key-value pairs). All of the map data structures provided in the JDK implement the map interface, the following is the source code of the map interface (the comments are too long, basic implementation specifications, for the sake of space I will try to omit).

package java.util;import java.util.function.BiConsumer;import java.util.function.BiFunction;import java.util.function.Function;import java.io.Serializable;public interface Map<K,V> {
The query Operation/** * Returns the number of key-value pairs contained in this map, and if it is greater than integer.max_value, the * should return integer.max_value. */int size ();/** * Map is empty. */boolean isEmpty ();/** * If the map contains key, False if True is returned. */boolean ContainsKey (Object key),/** * Whether the map contains value, or False if True is returned. */boolean Containsvalue (Object value);/** * finds value based on key and returns null if map does not contain the key. */v get (Object key);//Modify Operation/** * Add a pair of key-value pairs, if the map already contains this key, then the new value will overwrite the old value, * and return the old value, if there is no previous key in the map, then return NULL. */v put (K key, V value);/** * Deletes the specified key and returns the previous value, or null if the key is not in the map. */v Remove (Object key);//Bulk Operation/** * Bulk Add all key-value pairs in the specified map to the current map. */void Putall (map<? extends K,? extends v> m);/** * Deletes all key-value pairs in the Map. */void clear ();//Collection View/** * Returns the set containing all the keys in the map, all modifications to the view have the same effect on the map, and vice versa. */set<k> KeySet ();/** * Returns a collection containing all the value in the map, with all modifications to the view having the same effect on the map, and vice versa. */collection<v> values ();/** * Returns a set containing all the key-value pairs in the map, with all modifications to the view having the same effect on the map, and vice versa. */set<map.entry<k, v>> EntrySet ();/** * Entry represents a pair of key-value pairs that regulate some basic functions and several implemented class functions (various comparators). */interface entry<k,v>{K GetKey ();    V GetValue ();    V SetValue (v value);    Boolean equals (Object O);    int hashcode (); public static <k extends Comparable<? Super K>, v> comparator<map.entry<k,v>> Comparingbykey () {return (comparator<map.entry<k,    V>> & Serializable) (c1, C2), C1.getkey (). CompareTo (C2.getkey ()); } public static <k, V extends Comparable<? Super v>> comparator<map.entry<k,v>> Comparingbyvalue () {return (comparator<map.entry<k, V    >> & Serializable) (c1, C2), C1.getvalue (). CompareTo (C2.getvalue ());        } public static <k, v> comparator<map.entry<k, v>> comparingbykey (comparator<? Super K> CMP) {        Objects.requirenonnull (CMP); Return (comparator<map.entry<k, v>> & Serializable) (c1, C2), Cmp.compare (C1.getkey (), C2.    GetKey ()); } public static <k, v> COMPARATOR&LT;MAP.ENTRY&LT        K, v>> comparingbyvalue (comparator<? Super V> CMP) {objects.requirenonnull (CMP); Return (comparator<map.entry<k, v>> & Serializable) (c1, C2), Cmp.compare (C1.getvalue (), C    2.getValue ()); }}//Compare and hashing/** * Compares the specified object to this map for equality. */boolean equals (Object o);/** * Returns the hash code for this map. */int hashcode ();//default method (non-abstract method)/** * finds value based on key and returns DefaultValue if the key does not exist or is equal to NULL.    */default v Getordefault (Object key, v DefaultValue) {V V; Return (((v = Get (key)) = null) | | containskey (key))? V:defaultvalue;} /** * traverses the map and executes the specified action (action) on each key-value pair. * Biconsumer is a function interface (an interface with an abstract method to support Lambda), * It represents an operation that accepts two input parameters and does not return any results. * As for its strange name, according to the naming conventions of other function interfaces in Java, BI should be a binary abbreviation, meaning two yuan.    */default void ForEach (biconsumer<? Super K,? Super V> Action) {Objects.requirenonnull (action);        For (Map.entry<k, v> entry:entryset ()) {k k;        V V;            try {k = Entry.getkey ();        v = entry.getvalue (); } CAtch (illegalstateexception ise) {//This usually means the entry are no longer in the map.        throw new Concurrentmodificationexception (ISE);    } action.accept (k, v); }}/** * Iterates through the map and calls the incoming function functions to generate a new value to replace the old value. * Bifunction is also a function interface that accepts two input parameters and returns a result. */default void ReplaceAll (bifunction<? Super K,? Super V,? extends V> function) {objects.requirenonnull (functi    ON);        For (Map.entry<k, v> entry:entryset ()) {k k;        V V;            try {k = Entry.getkey ();        v = entry.getvalue ();            } catch (IllegalStateException ise) {//This usually means the entry are no longer in the map.        throw new Concurrentmodificationexception (ISE);        }//Ise thrown from function was not a CME.        v = function.apply (k, v);        try {entry.setvalue (v);         } catch (IllegalStateException ise) {//This usually means the entry are no longer in the map.   throw new Concurrentmodificationexception (ISE); }}/** * If the specified key does not exist or the associated value is NULL, a key-value pair is added.    */default v putifabsent (K key, V value) {V v = get (key);    if (v = = null) {v = put (key, value); } return v;} /** * The key is deleted when the value associated with the specified key is equal to the passed-in parameter value.    */default Boolean Remove (Object key, Object value) {Object curvalue = Get (key); if (!        Objects.equals (Curvalue, value) | | (Curvalue = = null &&!containskey (key)))    {return false;    } remove (key); return true;} /** * Replace with NewValue when the value associated with the specified key is equal to oldvalue.    */default Boolean replace (K key, v OldValue, v newvalue) {Object Curvalue = get (key); if (!        Objects.equals (Curvalue, oldValue) | | (Curvalue = = null &&!containskey (key)))    {return false;    } put (key, newvalue); return true;} /** * Replace when the specified key is associated to a value.    */default v replace (K key, V value) {v Curvalue; if ((Curvalue = Get (key)) = null) | | containskey (key)) {Curvalue = put (Key, ValUE); } return curvalue;} /** * When the specified key is not associated to a value or value is NULL, call Mappingfunction to generate the value and add a key-value pair to the map. * function is a functional interface that takes an input parameter and returns a result, and if the result returned by Mappingfunction * is also null, then the put is not called. */default V computeifabsent (k key, function<? Super K,? extends V> mappingfunction) {Objects.requirenonn    Ull (mappingfunction);    V V;        if ((v = Get (key)) = = null) {v newvalue;            if (NewValue = mappingfunction.apply (key)) = null) {Put (key, newvalue);        return newvalue; }} return v;} /** * When the specified key is associated to a value and is not NULL, the call remappingfunction generates NewValue, * If newvalue is not NULL, then replace it, otherwise delete the key. */default v computeifpresent (k key, bifunction<? Super K,? Super V,? Extends v> remappingfunction) {OBJ    Ects.requirenonnull (remappingfunction);    V OldValue;        if (OldValue = Get (key)) = null) {V newvalue = remappingfunction.apply (key, OldValue);            if (newvalue! = null) {Put (key, newvalue);    return newvalue;    } else {remove (key);        return null;    }} else {return null; }}/** * Remappingfunction generates newvalue based on the value associated with the key, and the key is deleted when newvalue equals null, otherwise the old mapping is added or replaced. */default v Compute (k key, bifunction<? Super K,? Super V,? Extends v> remappingfunction) {objects.requ    Irenonnull (remappingfunction);    V OldValue = Get (key);    V newvalue = remappingfunction.apply (key, OldValue); if (newvalue = = null) {//delete mapping if (oldValue! = NULL | | containskey (KEY)) {//Somethin            G to remove remove (key);        return null; } else {//do.            Leave things as they were.        return null;        }} else {//Add or replace old mapping put (key, newvalue);    return newvalue; }}/** * When the specified key is not associated to a value or value is NULL, it is associated with the passed-in parameter, value *. Otherwise, call Remappingfunction to generate the newvalue and replace it. * If NewValue equals null, then delete the key. */default v Merge (K key, V value, Bifunction<? Super V,? Super V,?    Extends V> remappingfunction) {objects.requirenonnull (remappingfunction);    Objects.requirenonnull (value);    V OldValue = Get (key); V NewValue = (OldValue = = null)?    Value:remappingFunction.apply (oldValue, value);    if (newvalue = = null) {remove (key);    } else {put (key, newvalue); } return newvalue;}

}
It is important to note that these default methods are non-thread-safe, and any extension classes that ensure thread safety must override these methods, such as Concurrenthashmap.

Map of the inheritance relationship structure diagram, it is also the next analysis of the map implementation class outline, these implementation classes are more commonly used, in the JDK map implementation class has dozens of, most of which we can not use, limited to the length of the reason is not explained (this article contains many source code and the implementation of the details of the analysis, Readers are advised to take a continuous period of free time to read slowly.

That little thing about the map big family (1): Map

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.