Map interface in Java set and Map interface in Java set

Source: Internet
Author: User
Tags comparable

Map interface in Java set and Map interface in Java set

Jdk1.8.0 _ 144

Map is one of the three Java collections in java. in the util package, Map, as an interface, defines some basic operations for this data structure. Its ultimate implementation classes include HashMap, TreeMap, SortedMap, and so on, most of these final child classes have a common abstract parent class AbstractMap. In AbstractMap, most Map implementation methods are implemented. This article introduces the methods defined by the Map interface and what are added by JDK8.

Map is translated as "ing". It is like a dictionary. Given a key value, it can directly locate the value. Its storage structure is in the form of "key: value, the core data structure defines an interface-Entry in Map, which contains a key and its corresponding value. First, let's look at the methods defined by the Map. Entry interface.

Interface Map. Entry <K, V>

K getKey ()

Obtain the key value.

V getValue ()

Obtain the value.

V setValue (V value)

Store value.

Boolean equals (Object o)

Int hashCode ()

These two methods have been mentioned in "the father of the ten classes -- Object", which is a method in the Object class. These two methods usually appear at the same time, that is to say, the intCode method needs to be rewritten to ensure that the equals method is not faulty. To rewrite equals, five rules (self-inversion, symmetry, transmission, consistency, and non-null) must be met ). Of course, it is specific about how to rewrite it. Here, as an interface, it is not explained but completed by its subclass.

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 they are all newly added generic methods for the simpler Map sorting. The generic methods here seem complicated, for the first method, let's briefly review the generic method.

The basic format of a generic method is that the list of generic parameters must be defined before the return value. The returned value of this method is Comparator <Map. Entry <K, V>, that is, its generic parameter list is "<K extends Comparable <? Super K>, V> ", which has two generic parameters: K and V. The parameter K must implement the Comparable interface.

How does JDK8 use the new method for Map sorting? Recall how JDK8 sorted Map before:

1/** 2 * Sort a Map by Keys. -- JDK7 3 * @ param map To be sorted Map. 4 * @ return Sorted Map. 5 */6 public Map <String, Integer> sortedByKeys (Map <String, Integer> map) {7 List <Map. entry <String, Integer> list = new vertex list <> (map. entrySet (); 8 Collections. sort (list, new Comparator <Map. entry <String, Integer> () {9 @ Override10 public int compare (Map. entry <String, Integer> o1, Map. entry <String, Integer> o2) {11 return o1.getKey (). compareTo (o2.getKey (); 12} 13}); 14 Map <String, Integer> linkedMap = new LinkedHashMap <> (); 15 Iterator <Map. entry <Strin g, Integer> iterator = list. iterator (); 16 while (iterator. hasNext () {17 Map. entry <String, Integer> entry = iterator. next (); 18 rows map. put (entry. getKey (), entry. getValue (); 19} 20 21 return struct map; 22}View Code

From the code of sorting Map by JDK 7, you need to first define the generic parameter as Map. list of Entry types, using Collections. sort sorts the List of sets, defines a LinkedHashMap, and traverses the elements in the List of sets into LinkedHashMap. That is to say, there is no similar Collections. the sort (Map, Comparator) method directly sorts the Map set types. JDK 8 has improved this by sorting Map by Stream class.

 1 /** 2  * Sort a Map by Keys.——JDK8 3  * @param map To be sorted Map. 4  * @return Sorted Map. 5  */ 6 public Map<String, Integer> sortedByKeys(Map<String, Integer> map) { 7     Map<String, Integer> result = new LinkedHashMap<>(); 8     map.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEachOrdered(x -> result.put(x.getKey(), x.getValue())); 9     return result;10 }

The amount of visible code is greatly reduced. In short, the four methods are the sort methods that JDK8 uses Stream classes and Lambda expressions to compensate for the lack of Map.

ComparingByKey () // sort by key values, but the Comparable interface must be implemented for the key value type.

ComparingByValue () // sort by value, but the Comparable interface must be implemented for the key value type.

ComparingByKey (Comparator) // sort by key values, but the key value does not implement the Comparable interface. A Comparator is required.

ComparingByValue (Comparator) // sorts values, but the value does not implement the Comparable interface. A Comparator is required.

Again, Comparator usesRule ModeInstead of modifying the original object, a new object is introduced to change the original object. If the key (or value) does not implement the Comparable interface, in this case, you can pass in a Comparator for sorting without modifying the original code. It is a bad thing to modify the original code.

Reference link: New Features of JDK 8-Lambda expressions-Comparable and Comparator

The method defined in the Map. Entry interface ends here. below is the method defined by the lock in the Map interface.

Int size ()

Returns the number of key-value pairs in the Map. The maximum value is Integer. MAX_VALUE (2 ^ 31-1 ).

Boolean isEmpty ()

If Map is empty, you can guess that if size () = 0, Map is empty.

Boolean containsKey (Object key)

Whether the Map contains the key value.

Boolean containsValue (Object value)

Whether the Map contains the value.

V get (Object key)

Obtain the corresponding value through the key value. If the Map does not contain the key value, null is returned. It is also possible that the value corresponding to the key value is null, in this case, you can use the containsKey method to determine whether the key value is included.

V put (K key, V value)

Store key-value pairs in Map and return the inserted value.

After JDK 5, Map is changed to a generic class. What if the get method parameter is not a generic K, but an Object? Including the above containsKey (Object) and containsValue (Object) parameters are also Object rather than generic. It seems more appropriate to use generics here. Consider the following scenarios:

This issue is also discussed in 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 compatibility that generics occur only in JDK1.5, while HashMap occurs only in jdk1.2. there are many compatibility problems when generics occur, in order to ensure its compatibility, you must not do some processing, such as the extensive type erasure. Assume that the following code exists before JDK1.5:

1 HashMap hashMap = new HashMap();2 ArrayList arrayList = new ArrayList();3 hashMap.put(arrayList, "this is list");4 System.out.println(hashMap.get(arrayList));5 LinkedList linkedList = new LinkedList();6 System.out.println(hashMap.get(linkedList));

This code can run well without using generics. If the parameters in the get method change to generics rather than objects, then hashMap. the get (sorted list) Statement will cause an error during compilation because it is not of the ArrayList type.

2. The Key type cannot be determined. Here is an example:

1 public class HashMapTest {2 public static void main (String [] args) {3 HashMap <SubFoo, String> hashMap = new HashMap <> (); 4 // SubFoo is a subclass of the Foo Class 5 test (hashMap); // an error occurred during compilation 6} 7 8 public static void test (HashMap <Foo, String> hashMap) {// The parameter is HashMap, and the key value is the Foo class, but it cannot receive its subclass 9 System. out. println (hashMap. get (new Foo (); 10} 11}

In this case, change the parameter type in the test method to HashMap <? Extends Foo, String>. However, this is true only when the parameter type of the get method is Object. If the parameter type of the get method is generic, then it is Extends Foo "is unknown. In other words, the compiler does not know whether it should receive the Foo type, SubFoo type, or even SubFoo type. For the second hypothesis, many netizens pointed out that the parameter type of the get method can be "<T extends E>", which can avoid the second problem.

During discussions with foreign netizens, I still prefer the first compatibility problem. After all, generics appear later. For the author John, they also said that they are trying to make them generic, however, a series of problems have arisen after generics, which has to cause them to abandon generics. In fact, in the get method comment of the source code, we can see that put is also of the Object type before. After the appearance of generics, The put method can be successfully transformed into generics, get has to give up generics to consider compatibility issues.

V remove (Object key)

Delete key-value pairs in Map.

Void putAll (Map <? Extends K ,? Extends V> m)

The parameter of this method is a Map, which puts all input maps into this Map. Of course, there are requirements for the parameter Map, "? Extends K "means that the key value of the input Map must be the key or subclass of the Map. The same applies to the value.

Void clear ()

Remove all key-value pairs in Map.

Set <K> keyset ()

Returns the set of keys. Note that the set is unordered and duplicate values cannot be stored. Of course, duplicate key values cannot exist in Map, nor are there any unordered values. In fact, the use of this method is a bit interesting, which involves some knowledge about Java object reference.

1 Map<String, Integer> map = new HashMap<String, Integer>();2 map.put("a", 1);3 map.put("b", 2);4 System.out.println(map.keySet());        //output: [a, b]5 Set<String> sets = map.keySet();6 sets.remove("a");7 System.out.println(map.keySet());        //output: [b]8 sets.add("c");        //output: throws UnsupportedOperationException9 System.out.println(map.keySet());

The set of keys in the Map is output in Row 3, that is, "[a, B]".

Then create a set object pointing to the map. keySet () method to return the set, and delete the "a" element through this set object. Then print the set of keys using the map. keySet () method, and you will find that "[B]" is printed at this time. This is because we areVirtual Machine StackIts pointer to the sets object defined on is map. the objects returned by keySet (), that is, the two point to the same address. Any change to the keySet () will affect the object itself. This is also the definition of this method by the Map interface, at the same time, the Map interface also imposes another restriction on this method. The Set object returned by keySet () cannot be used to add the method. At this time, the UnsupportedOperationException will be thrown, the reason is very simple. If an element is added to the Set object and the corresponding Map key has it, what is its corresponding value?

Collection <V> values ()

Returns a Collection of value values. This set is directly raised to the Collection's top-level parent interface-Collection. Why is it not a Set object? The reason is also very simple. It is reasonable to return the Set object repeatedly with the key value, but the value must be repeated. It is obviously inappropriate to return the Set object. If only the List object is returned, it is not appropriate, returns the top-level parent interface -- Collection.

Set <Map. Entry <K, V> entrySet ()

Returns the Set of Map. Entry.

Boolean equals (Object o)

Int hashCode ()

Equals is simply implemented using "=" in the Object class. To compare whether two maps have equal values, we need to override the equals method. to override the equals method, we usually need to override the hashCode method. To rewrite the equals method, five principles must be followed: Self-inversion, symmetry, transmission, consistency, and non-null. After these principles are met, the two objects equals must be equal, and their hashCode hash values must be equal. However, the hashCode hash values are equal, the two objects equals are not necessarily equal.

Default V getOrDefault (Object key, V defaultValue)

This method is only available in JDK 8, and a new feature of JDK 8 is used to implement a method in the interface called the default method. Similar to the abstract class, the default method is a specific method. This method mainly makes up for the scenario encountered during the Encoding Process: If a Map does not have a key value, a value is saved. In the past, I wrote a contanisKey method to determine whether to use the contanisKey method. Now I only need one sentence to get the map. put ("a", map. getOrDefault ("a", 2); its implementation is also very simple, that is, to determine whether the key value exists in the Map. If it does not exist, it is saved to the defaultValue parameter in getOrDefault, if yes, it is stored in the previous value parameter again. (V = get (key ))! = Null) | containsKey (key ))? V: defaultValue;

Default void forEach (BiConsumer <? Super K ,? Super V> action)

This method is also added to JDK 8. For more convenient traversal, this method is almost added to the JDK8 set. This new API can be used to easily traverse elements in the set, the use of this method must be combined with the 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 in Map. Lambda expressions are used as parameters, for example:

1 map. replaceAll (k, v)-> 10); // replace all values in the Map with 102 map. replaceAll (k, v)-> {// if the key value in the Map is equal to a, the value is replaced with 103 if (k. equals ("a") {4 return 10; 5} 6 return v; 7 });

Default V putIfAbsent (K key, V value)

There is also a putIfAbsent method in ConcurrentHashMap. If the key value of the method does not exist, it is inserted. If the key value does not exist, it is not inserted. This method is also directly added to Map in JDK 8. The ConcurrentHashMap # putIfAbsent method has the same meaning and is equivalent:

1 if (!map.containsKey(key, value)) {2     map.put(key, value);3 } else {4     map.get(key);5 }

We mentioned a method similar to this -- getOrDefault. Do not confuse it. Calling putIfAbsent will insert it directly, while getOrDefault will not insert it directly into Map.

Default boolean remove (Object key, Object value)

The original remove method directly transfers a key to remove the corresponding key-value pair from the Map. The new method must satisfy both the key and value requirements and be deleted only when the Map has a corresponding key-value pair.

Default boolean replace (K key, V oldValue, V newValue)

Similar to replaceAll, when the key-oldValue key-value pair in the parameter exists in Map, newValue is used to replace oldValue.

Default V replace (K key, V value)

This method is an overload of the above method. Instead of judging the value corresponding to the key value, it directly replaces the original value of the key value with the value.

Default V computeIfAbsent (K key, Function <? Super K ,? Extends V> mappingFunction)

If the key value does not exist in the Map, call the function body in the Lambda expression to calculate the value and put it in the Map. The next time you get the value, you can directly obtain it from the Map. This can be seen everywhere in Map implementation local cache. This method is similar to the following code:

1 if (map. get (key) = null) {2 value = func (key); // calculate the value 3 map. put (key, value); 4} 5 return map. get (key );

Default V computeIfPresent (K key, BiFunction <? Super K ,? Super V ,? Extends V> remappingFunction)

Given a key value, this method can use Lambda expressions to calculate the new value generated by the custom key and value. If the new value is null, the corresponding key value in the Map is deleted, if not empty, replace the old value with a new one.

Default V compute (K key, BiFunction <? Super K ,? Super V ,? Extends V> remappingFunction)

This method is the combination of the above two methods. You can use this method in both of the above two places. The function body of the Lambda expression uses the Three-wood operator.

Default V merge (K key, V value, BiFunction <? Super V ,? Super V ,? Extends V> remappingFunction)

"Merge" means that both the old value and new value are involved in calculation and replication. Given the key and value parameters, if the key value exists in the Map, the old value and the given value are used together to calculate the new value as the key value. If the new value is null, then, the key is deleted from the Map. If the key does not exist, the given value is directly used as the key value.

The Map ing set type is one of the most important and commonly used data structures in Java. The Map interface is their base class and defines many basic methods in this interface, the specific practice is completed by its subclass. JDK 8 has added many default methods in the Map interface, which also provides great convenience for us in actual encoding, if JDK 8 is used as the development environment, you may wish to learn more about using new APIs.

  

 

This is a public number that can add buff to programmers.

Related Article

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.