The map interface in the Java collection

Source: Internet
Author: User
Tags comparable set set

jdk1.8.0_144

Map is one of the three collections of Java in the Java.util package, map as an interface exists to define the basic operation of this data structure, its final implementation class has many: HashMap, TreeMap, SortedMap, etc., Most of these final subclasses have a common abstract parent class Abstractmap. In Abstractmap, most map implementations are implemented in a common way. This article describes which methods are defined by the map interface, and which are added to the JDK8.

Map is translated as "map", it is like a dictionary, given a key value, you can directly locate the value of its storage structure is "key:value" form, the core data structure within the map defines an interface--entry, This data structure contains a key and its corresponding value. The first step is to spy on what methods the Map.entry interface defines.

Interface Map.entry<k, v>

K GetKey ()

Gets the key value.

V GetValue ()

Gets the value values.

V SetValue (v value)

Stores value values.

Boolean equals (Object O)

int Hashcode ()

These two methods I mentioned in "Water's father--object", this is the method in the Object class, these two methods are usually at the same time, that is, to rewrite the Equals method in order to ensure that there is no problem often need to rewrite the Intcode method. overriding equals requires 5 rules (reflexivity, symmetry, transitivity, consistency, non-nullability). Of course, this is exactly how it is rewritten, which is not explained here as an interface but is done by its subclasses.

public static <k extends Comparable<? Super K>, v> comparator<map.entry<k,v>> Comparingbykey ()

public static <k, V extends Comparable<? Super v>> comparator<map.entry<k,v>> Comparingbyvalue ()

public static <k, v> comparator<map.entry<k, v>> comparingbykey (comparator<? Super K> CMP)

public static <k, v> comparator<map.entry<k, v>> comparingbyvalue (comparator<? Super V> CMP)

These four methods are put together because this is the JDK8 for a simpler ordering of the new generic method, where the generic method seems to be more complex, we have a brief look at the first method of the generic method.

The basic format for a generic method is that the generic parameter list needs to be defined before the return value. The return value of this method returns COMPARATOR<MAP.ENTRY<K, V>>, which means that its generic parameter list is "<k extends comparable< Super K>, v> ", has two generic parameters K and V. Parameter k requires implementation of the comparable interface.

Since this is the new method JDK8 for map sorting, how is it used? Recall how the map was sorted before JDK8:

1 /**2 * Sort a Map by Keys.--jdk73  * @parammap to is sorted map.4  * @returnSorted Map.5  */6  PublicMap<string, integer> Sortedbykeys (map<string, integer>map) {7list<map.entry<string, integer>> list =NewLinkedlist<>(Map.entryset ());8Collections.sort (list,NewComparator<map.entry<string, integer>>() {9 @OverrideTen          Public intCompare (map.entry<string, integer> O1, map.entry<string, integer>O2) { One             returnO1.getkey (). CompareTo (O2.getkey ()); A         } -     }); -map<string, integer> linkedmap =NewLinkedhashmap<>(); theIterator<map.entry<strin g, integer>> Iterator =list.iterator (); -      while(Iterator.hasnext ()) { -map.entry<string, integer> Entry =Iterator.next (); - Linkedmap.put (Entry.getkey (), Entry.getvalue ()); +     } -  +     returnLinkedmap; A}
View Code

From the JDK7 version of the code to sort the map can be seen, First, you need to define a generic parameter for the Map.entry type list, use Collections.sort to sort the collection list, then define a linkedhashmap, and iterate over the elements in the collection list into Linkedhashmap, that is, there is not a similar Coll The Ections.sort (map, Comparator) method directly sorts the map collection types. JDK8 has improved this by sorting the map by the stream class.

1 /**2 * Sort a Map by Keys.--jdk83  * @parammap to is sorted map.4  * @returnSorted Map.5  */6  PublicMap<string, integer> Sortedbykeys (map<string, integer>map) {7map<string, integer> result =NewLinkedhashmap<>();8Map.entryset (). Stream (). Sorted (Map.Entry.comparingByKey ()). foreachordered (X-Result.put (X.getkey (), X.getvalue ()));9     returnresult;Ten}

The amount of visible code is greatly reduced, in a nutshell, these four methods are JDK8 using the stream class and lambda expressions to compensate for the missing ordering method of the map.

Comparingbykey ()//The key value is used to sort, but requires the key value type to implement the comparable interface.

Comparingbyvalue ()//Use the value values to sort, but require the key value type to implement the comparable interface.

Comparingbykey (Comparator)//Use the key value to sort, but the key value does not implement the comparable interface and needs to pass in a Comparator comparer.

Comparingbyvalue (Comparator)//is sorted with value values, but the value values do not implement the comparable interface and need to pass in a Comparator comparer.

To say one more thing, comparator adopts the strategy mode , that is, not modifying the original object, but introducing a new object to change the original object, where if key (or value) does not implement the comparable interface, It is a bad thing to make changes to the old code by passing in a comparator comparer without modifying the original code.

Reference Links: New features of JDK8--LAMBDA expression "indefinitely comparable and comparator"

This concludes the method defined in the Map.entry interface, which is the method of the lock definition in the map interface.

int size ()

Returns the number of Key-value key-value pairs in the map, with a maximum value of Integer.max_value (2^31-1).

Boolean IsEmpty ()

If the map is empty, you can guess if size () = 0,map is empty.

Boolean ContainsKey (Object key)

Whether the map contains a key key value.

Boolean Containsvalue (Object value)

Whether the map contains value values.

V get (Object key)

Gets the corresponding value value from the key value. If the map does not contain a key value to return NULL, it is also possible that the key value corresponding to the value is null, at this point to be distinguished, you can first use the ContainsKey method to determine whether to include the key value.

V Put (K key, V value)

Stores the Key-value key value pair in the map and returns the value of the inserted value.

Map changed from JDK5 to generic class, and the Get method's parameters are not generic K, but an object? Including the ContainsKey (object) and Containsvalue (object) parameters above are also Object instead of generics. In this place it seems to be more appropriate to use generics. Consider the following scenarios:

    1. At first I wrote a piece of code, defining hashmap<string, String>, defining hashmap<string, String> At this point I put ("a", "a"), and I get the value through get ("a").
    2. Writing, I found that I should be defined as Hashmap<integer, string> At this point the IDE automatically makes an error in the put ("a", "a") method, because the generic parameter type of MAP key is modified for Integer, I can find it well and correct it. However, my get ("a") does not have any hint, because its argument is that object can receive any type of value, if my Get method is also used generics at this time the IDE will remind me this place parameter type is wrong, should be an integer type. So why does the Get method use the object type instead of the generic? Didn't the JDK author think of that? Clearly can be found in the compilation of the problem, why should be at run time to judge?

This issue is also discussed on StackOverflow, Link: https://stackoverflow. com/questions/1926285/why-does-hashmapcontainskey-take-an-parameter-of-type-object,http:// Smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html I have roughly translated this may have the following reasons:

1. This is to ensure that compatibility generics are present in JDK1.5, while HashMap is only present in JDK1.2, when generics occur with many compatibility issues, in order to ensure compatibility has to do some processing, such as generic type of erasure and so on. Suppose the following code exists before JDK1.5:

1 New HashMap (); 2 New ArrayList (); 3 hashmap.put (arrayList, "This is List"); 4 System.out.println (Hashmap.get (arrayList)); 5 New LinkedList (); 6 System.out.println (Hashmap.get (LinkedList));

This code can run well without generics, and if the parameters in the Get method become generic instead of object, then Hashmap.get (LinkedList) will error at compile time because it is not a ArrayList type.

2. Cannot determine the type of key. Here's an example:

1  Public classHashmaptest {2      Public Static voidMain (string[] args) {3Hashmap<subfoo, string> HashMap =NewHashmap<>(); 4 //Subfoo is a subclass of the Foo class5Test (HASHMAP);//compile-time error6 }7 8  Public Static voidTest (Hashmap<foo, string> HashMap) {//The parameter is the Hashmap,key value is the Foo class, but it cannot receive its subclasses9System.out.println (Hashmap.get (NewFoo ()));Ten     } One}

The above scenario modifies the parameter type in the test method to hashmap< Extends Foo, string>. But this is correct if the parameter type of the Get method is object, and if the parameter type of the Get method is generic, then it is for "? Extends foo "is ignorant, in other words, the compiler does not know whether it should receive the Foo type or the Subfoo type, or even the Subsubfoo type. For the second hypothesis, many netizens have pointed out that the parameter type of the Get method can be "<t extends e>", which avoids the second problem.

In the discussion of foreign netizens, I still prefer the first compatibility problem, after all, the generics are relatively late, for the author John also said that they try to generics, but after the generics produced a series of problems, which had to let them abandon their generics. In fact, in the source of the Get method comments can be seen in the previous put is the object type, after the occurrence of generics, the put method can be successfully transformed into generics, and get to consider compatibility issues have to abandon it to generics.

V Remove (Object key)

Delete the Key-value key-value pairs in the map.

void Putall (map<? extends K,? extends v> m)

The parameter of this method is a map that puts the incoming map all into this map, of course the parameter map is required, "? Extends K "means that the incoming map's key value needs to be the key or subclass of this map, and value is the same.

void Clear ()

Removes all Key-value key-value pairs from the map.

Set<k> keyset ()

Returns the set set of key, noting that set is unordered and cannot store duplicate values, and there is no possibility that duplicate key values exist in the map, and there are no ordered unordered words. In fact, the use of this method is somewhat interesting, this will involve the Java object reference related knowledge.

1map<string, integer> map =NewHashmap<string, integer>();2Map.put ("A", 1);3Map.put ("B", 2);4System.out.println (Map.keyset ());//output: [A, b]5Set<string> sets =Map.keyset ();6Sets.remove ("a");7System.out.println (Map.keyset ());//output: [b]8Sets.add ("C");//output:throws unsupportedoperationexception9System.out.println (Map.keyset ());

The output of line 4th is the set set of key in map, which is "[A, b]".

A set object is then created to point to the Map.keyset () method to return the set's collection, and the "a" element is removed from the set object. At this point, the Map.keyset () method is used to print the collection of keys, and you will find that "[b]" is printed at this time. This is because the sets object that we define on the virtual machine stack is pointing to the object returned by Map.keyset (), which means that the two points to the same address, so as long as any one by one changes to it will affect the object itself, This is also the map interface to the definition of this method, and the map interface to the method also made another restriction, not through the keyset () returned by the Set object to add operation, this will throw a unsupportedoperationexception exception, The reason is simple. If you add an element to the set object, the corresponding map key has, then its value?

Collection<v> VALUES ()

Returns a collection collection of value values. This set rises directly to the top parent interface--collection of the collection. Why is it not a set object? The reason is also very simple, the key value can not be returned repeatedly set object is reasonable, but the value can certainly be repeated, the return of the set object is obviously inappropriate, if only return the list object, that is not appropriate, simply return to the top-level parent interface--collection.

Set<map.entry<k, v>> EntrySet ()

Returns the set set of Map.entry.

Boolean equals (Object O)

int Hashcode ()

Equals is simply implemented with the "= =" in the object class, which obviously requires overriding the Equals method for comparing two map values, and overriding the Equals method often requires overriding the Hashcode method. Overriding the Equals method requires the following 5 principles: reflexivity, Symmetry, transitivity, consistency, non-nullability. The following principles are met: two objects equals equal, their hashcode hash values are equal, but hashcode hash values are equal, and two objects equals are not necessarily equal.

Default v Getordefault (Object key, v DefaultValue)

This method is JDK8, and uses a new feature of JDK8, which implements a method in an interface called the default method, similar to an abstract class, and the default method is a concrete method. This approach is mainly to compensate for the scenario encountered in the encoding process: if a map does not have a key value, then a value is stored. Used to write a judgment using the Contaniskey method, now only need a word can be done map.put ("a", Map.getordefault ("a", 2)); Its implementation is also very simple, is to determine whether the key value in the map exists, does not exist in the Getordefault in the DefaultValue parameter, there is a second deposit of the previous value parameter. (((v = Get (key))! = null) | | containskey (key))? V:defaultvalue;

default void ForEach (BICONSUMER<? Super K,? Super v> Action)

This method is also JDK8 new, for more convenient traversal, this method is almost new in the JDK8 collection, using this new API can easily traverse the elements in the collection, the use of this method needs to be combined with a lambda expression: Map.foreach ((k, V) System.out.println ("key=" + K + ", value=" + V))

default void ReplaceAll (BIFUNCTION<? Super K,? Super V,? extends V> function)

Replace the value values in the map with a lambda expression as a parameter, for example:

1 map.replaceall (k, v);    // Replace all values in map with 2 map.replaceall (k, v) {        // if the key value in map is equal to a, its value is replaced by3if      (K.equals ("a")) {4         return ; 5     }6     return  v; 7 });

Default v putifabsent (K key, V value)

In Concurrenthashmap there is also a putifabsent method, which means that the key value does not exist on the insertion, and the presence is not inserted. This method is also added directly to the map in JDK8, this method concurrenthashmap#putifabsent the same meaning, this method is equivalent to:

1 if (! Map.containskey (key, value)) {2    map.put (key, value); 3 Else {4    map.get (key); 5 }

Before mentioned a method and this similar to--getordefault. Be careful not to confuse, the call putifabsent will be inserted directly, and Getordefault will not be inserted directly into the map.

Default Boolean remove (Object key, Object value)

The original Remove method is to pass a key directly from the map to remove the corresponding Key-value key value pair. The new method needs to satisfy both key and value while the map has corresponding key-value pairs to delete

Default Boolean replace (K key, v OldValue, v newvalue)

Similar to ReplaceAll, when the Key-oldvalue key value pair in the parameter is present in the map, the oldvalue is replaced with NewValue.

Default v replace (K key, V value)

This method is overloaded with the above method, does not determine the value of the value corresponding to the key, but instead uses value to replace the value of the key value originally corresponding.

Default V computeifabsent (k key, function<? Super K,? extends V> mappingfunction)

If the key value does not exist in the map, the function body in the lambda expression is called to calculate the value and then put it in the map, which is fetched directly from the map the next time it gets fetched. This is actually everywhere in the map implementation local cache, which is similar to the following code:

1 if NULL {2     value = func (key);      // Calculating Value Values 3     map.put (key, value); 4 }5return map.get (key);

Default V computeifpresent (k key, bifunction<? Super K,? Super V,? Extends v> remappingfunction)

This method, given a key value, computes the new value value produced by the custom key and value through a lambda expression, and if the new value value is null, the corresponding key value in the map is deleted and the old value is replaced with a new one if it is not empty.

Default V Compute (k key, bifunction<? Super K,? Super V,? Extends v> remappingfunction)

This method is a combination of the above two methods, which can be used at the same time as the above two, where the function body of the lambda expression uses the tri-wood operator.

Default V merge (K key, V value, bifunction<? Super V,? Super V,? Extends v> remappingfunction)

Merge means that both old and new values are involved in the calculation and replication. Given the key and value parameter, if the key value exists in the map, the old value is computed with the given value as the value of the key, and if the new value is NULL, the key is removed from the map. If key does not exist, the given value is directly the value of the key.

The map map collection type is one of the most important and most commonly used data structures in Java, and the map interface is their base class, where many basic methods are defined, and the actual internship is done by its subclasses. JDK8 has a number of default methods in the map interface, which is also a great convenience for us in actual coding, so if you use JDK8 as a development environment, you may want to learn to use the new API.

  

This is a public number that can give the programmer a buff.

The map interface in the Java collection

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.