Java collection Map interface

Java collection Map interface

Map interface

Features (JDK8)

  1. Map and Collection exist side by side. Used to save data with mapping relationship: key value
  2. The key and value in the Map can make data of any reference type encapsulated in the HashMap$Node object
  3. The key in the Map cannot be repeated, and is willing to be the same as the HashSet
  4. The value in the Map can be repeated
  5. The key and value of Map can be null. Note that there can only be one null key
  6. String class is often used as the key of Map
  7. There is a one-way one-to-one relationship between key and value, that is, the corresponding value can always be found through the specified key
  8. put elements with the same key will be replaced

Map system inheritance diagram

data structure

  1. The key value of the data stored in the Map is placed in a HashMap$Node (the Entry interface is implemented)

    static class Node<K,V> implements Map.Entry<K,V> {
            final int hash;
            final K key;
            V value;
            Node<K,V> next;
    
            Node(int hash, K key, V value, Node<K,V> next) {
                this.hash = hash;
                this.key = key;
                this.value = value;
                this.next = next;
            }
    
            public final K getKey()        { return key; }
            public final V getValue()      { return value; }
            public final String toString() { return key + "=" + value; }
    
            public final int hashCode() {
                return Objects.hashCode(key) ^ Objects.hashCode(value);
            }
    
            public final V setValue(V newValue) {
                V oldValue = value;
                value = newValue;
                return oldValue;
            }
    
            public final boolean equals(Object o) {
                if (o == this)
                    return true;
                if (o instanceof Map.Entry) {
                    Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                    if (Objects.equals(key, e.getKey()) &&
                        Objects.equals(value, e.getValue()))
                        return true;
                }
                return false;
            }
        }
    
  2. The Map.Entryj interface in set < map. Entry < K, V > > obtained by entrySet() method directly refers to the data in Node and is not copied (so modification will affect the original data)

    interface Entry<K,V> {
            K getKey();
            V getValue();
            V setValue(V value);
        
            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<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
                Objects.requireNonNull(cmp);
                return (Comparator<Map.Entry<K, V>> & Serializable)
                    (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
            }
        }
    
  3. Like keySet(), it returns an internal class (which implements Set) and directly references the key in the original Node

    final class KeySet extends AbstractSet<K> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<K> iterator()     { return new KeyIterator(); }
        public final boolean contains(Object o) { return containsKey(o); }
        public final boolean remove(Object key) {
            return removeNode(hash(key), key, null, false, true) != null;
        }
        public final Spliterator<K> spliterator() {
            return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }
    
  4. values() also returns an internal class (implementing the Collection interface) that directly references the value in the Node

    final class Values extends AbstractCollection<V> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<V> iterator()     { return new ValueIterator(); }
        public final boolean contains(Object o) { return containsValue(o); }
        public final Spliterator<V> spliterator() {
            return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super V> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.value);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }
    

method

voidclear() deletes all mappings from the Map (optional).
default VCompute (k key, bifunction <? Super K,? Super V,? Extensions V > remoppingfunction) attempts to calculate the mapping of the specified key and the value of its current mapping (null if there is no current mapping).
default VComputeifabsent (k key, function <? Super K,? Extensions V > mappingfunction) if the specified key has not been associated with a value (or mapped to null), try to calculate its value using the given mapping function and enter it into this mapping unless null.
default VComputeifpresent (k key, bifunction <? Super K,? Super V,? Extensions V > remappingfunction) if the value of the specified key exists and is not empty, try to calculate a new mapping of the given key and its current mapping value.
booleancontainsKey(Object key) returns true if the mapping contains the mapping of the specified key.
booleancontainsValue(Object value) returns true if this Map maps one or more keys to the specified value.
Set<Map.Entry<K,V>>entrySet() returns the name of the Map contained in this Map Set View.
booleanequals(Object o) compares the specified object to this mapping for equality.
default voidForeach (biconsumer <? Super K,? Super V > action) performs the given operation on each entry in this map until all entries are processed or the operation throws an exception.
Vget(Object key) returns the value mapped to the specified key, or null if the mapping contains the mapping of the key.
default VgetOrDefault(Object key, V defaultValue) returns the value mapped by the specified key, or defaultValue if the mapping contains the mapping of the key.
inthashCode() returns the hash code value of this Map.
booleanisEmpty() returns true if the Map does not contain a key value mapping.
Set<K>keySet() returns the name of the key contained in this Map Set View.
default VMerge (k key, V value, bifunction <? Super V,? Super V,? Extensions V > remoppingfunction) if the specified key is not associated with a value or null, it is associated with the given non null value.
Vput(K key, V value) associates the specified value with the specified key in the map (optional operation).
voidPutall (Map <? Extensions K,? Extensions V > m) copies all the mappings of the specified Map to this Map (optional).
default VputIfAbsent(K key, V value) if the specified key has not been associated with a value (or mapped to null), associate it with the given value and return null, otherwise return the current value.
Vremove(Object key) if it exists (from an optional operation), delete a key mapping from the Map.
default booleanremove(Object key, Object value) deletes the entry only when the specified key is currently mapped to the specified value.
default Vreplace(K key, V value) the entry of the specified key can be replaced only when the target is mapped to a value.
default booleanreplace(K key, V oldValue, V newValue) can replace the entry of the specified key only when it is currently mapped to the specified value.
default voidReplaceall (bifunction <? Super K,? Super V,? Extends V > function) replaces the value of each entry with the result of calling the given function on the entry until all entries are processed or the function throws an exception.
intsize() returns the number of key value mappings in this Map.
Collection<V>values() returns the values contained in this Map Collection view

Map interface traversal mode

  1. Take out all keys, and then take out the corresponding value through the key

    Set keySet = map.keySet();
    //Enhanced for
    for(Object key:keySet){
        System.out.println(key + "=" + map.get(key));
    }
    //iterator 
    Iterator iterator = keySet.iterator();
    while(iterator.hasNext()){
        Object key = iterator.next();
        System.out.println(key + "=" + map.get(key));
    }
    
  2. Take out all the values

Collection values = map.values();
//Enhanced for
for(Object value:values){
    System.out.println(value);
}
//iterator 
Iterator iterator = keyset.iterator();
while(iterator.hasNext()){
    Object value = iterator.next();
    System.out.println(value);
}
  1. Get k-v through EntrySet

    Set entrySet = map.entrySet();
    //Enhanced for
    for(Object entry:entrySet){
        //Convert entry to Map.Entry
        Map.Entry m = (Map.Entry) entry;
        System.out.println(m.getKey() + "=" + m.getValue(key));
    }
    //iterator 
    Iterator iterator = entrySet.iterator();
    while(iterator.hasNext()){
        Object entry = iterator.next();//HashMap&Node implement Map.Entry
        Map.Entry m = (Map.Entry) entry;
        System.out.println(m.getKey() + "=" + m.getValue(key));
    }
    

Keywords: Java

Added by rulinus on Thu, 04 Nov 2021 22:21:14 +0200