The first learning notes Map collection of Java

Posted by allyse on Wed, 13 Oct 2021 16:41:40 +0200

Map collection  

Both are double column sets, storing K-V

Interface features  

Note: 1. Set is also a Key - Value structure, but its Value is always PRESENT, so it can be regarded as a Key.  

        2. Although duplicate key s are not allowed, they will be overwritten if they are added repeatedly.

        3. Input with put method, specify key with get method, and return value.

Create EntrySet internally

    k-v finally HashMap$Node node = newNode(hash,key,value,null). Note that k-v to facilitate the programmer's traversal, the EntrySet set, KeySet set and Values set will also be created internally. The KeySet stores keys and Values (of course, it is only a reference (address)! It is not a real Node, but a real Node is in the Node). The EntrySet includes KeySet and Values, and the operation type of the content is Node.

    In the entrySet, the type of stored elements is map. Entry < K, V > (entrySet is equivalent to an array). The real place to store k-v is HashMap$Node.   

    Why it can be transformed: because the Node class implements the entry interface. When the Node object is stored in the entrySet, it is convenient for us to traverse, because Map.Entry provides important methods getKey and getValue.

    If you only want to use key, use KeySet. If you only want to use value, use values. If you want to use both, use EntrySet.

 

    public static void main(String[] args) {
        Map a = new HashMap();
        a.put("Zhang San",18); //The put method adds a key value pair
        a.put("Li Si",20);
        a.put("Wang Wu",21);
        Set b = a.entrySet(); // Use entrySet to traverse. The parent class of entrySet is Set, so use Set to receive
        for (Object obj : b) {
            Map.Entry t = (Map.Entry)obj; //Downward transformation, and the compilation type is Map.Entry
            System.out.println(t.getKey()+" " + t.getValue());
        }
        Set c = a.keySet(); //Only key s can be operated
        Collection d = a.values(); //Only value can be manipulated
    }

Basic method

    public static void main(String[] args) {
        Map a = new HashMap();
        a.put("Zhang San",18);
        a.put("Li Si",9);
        a.put("Wang Wu",31);
        a.put("still",20);
        System.out.println(a);//{Li Si = 9, Zhang San = 18, Wang Wu = 31, Shang = 20}
        a.remove("Li Si");  //Delete a node according to a Key
        System.out.println(a);//{Zhang San = 18, Wang Wu = 31, Shang = 20}
        System.out.println(a.get("Zhang San"));//18 return value according to Key
        System.out.println(a.size());//3 
        System.out.println(a.isEmpty());//false
        System.out.println(a.containsKey("Wang Wu"));//true to find out whether this Key exists
        a.clear(); //eliminate
        System.out.println(a.isEmpty());//true
    }

traversal method

Using keySet

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("Zhang San",18);
        map.put("Li Si",9);
        map.put("Wang Wu",31);
        map.put("still",20);
        Set set = map.keySet(); //Get all key s
        //The first method enhances the for loop
        for (Object key : set) {
            System.out.println(key + "->" + map.get(key));//Get value with get method
        }
        //The second method iterators
        Iterator iterator = set.iterator(); //Gets the iterator of the set object
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "->" + map.get(key));
        }
    }

Use values

        Collection values = map.values(); //Get values
        for (Object key : values) { //Enhanced for
            System.out.println(key); //Note that there is no method to get the key from value in the Map
        }
        Iterator iterator = values.iterator(); //iterator  
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key);
        }

Using EntrySet

        Set set = map.entrySet(); // entrySet is a subclass of Set and an internal class of Map
        //1. Enhance for
        for (Object entry : set) {
            Map.Entry t = (Map.Entry)entry; // entry is an Object class and needs to be transformed downward
            System.out.println(t.getKey() + "->" + t.getValue());
        }
        //2. Iterator
        Iterator iterator = set.iterator(); 
        while (iterator.hasNext()) {
            Map.Entry h = (Map.Entry)iterator.next(); //One step writing
            System.out.println(h.getKey() + "->" + h.getValue());
        }

P534 value is the case when the object needs to call the method  

for (Object o : s) {
    Map.Entry t = (Map.Entry)o;
    if(((Employee)t.getValue()).getSal()>18000)  //Note that the method should be preceded by parentheses as a whole
    if((Employee)t.getValue().getSal()>18000) //This is wrong
    ...
}

for (Object o : s) {  //More readable
    Map.Entry t = (Map.Entry)o;
    Employee ee = (Employee) t;
    if(ee.getSal()>18000)
}

HashMap bottom  

HashMap underlying source code

  Because the bottom layer of HashSet is HashMap, the bottom layer is almost the same.

  1. Execute the constructor new HashMap(), initialize the loading factor loadfactor = 0.75, HashMap$Node[] table = null.

    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
    transient Node<K,V>[] table;

2. Execute put, call the hash method, and calculate the hash value of the key (note that to enter a method, you'd better use force step into).

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

3. Execute putVal method, and specific comments have been given in HashSet.

HashTable

Capacity expansion

The bottom layer has an array Hashtable$Entry [], with an initialization size of 11. The threshold is 8 = 11 * 0.75.

Call the in the put method   addEntry(hash, key, value, index);   When satisfied   if (count >= threshold)   Capacity expansion (rehash)

int newCapacity = (oldCapacity << 1) + 1; //New capacity calculation method
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
 // Critical value calculation method

Properties

Java read / write Properties configuration file - Xudong blog - blog Park   If you are interested, you can read this article.

matters needing attention

1. Properties inherit Hashtable and are out of order.

2. Data can be stored through k-v. of course, key and value cannot be null.

3. Common methods: add put(key,value), delete remove(key), change put (the same key,value), and check get(key).

How to select collection implementation classes in development

A group of objects means that there are only key s and no value s.  

TreeSet

Construction method

The normal TreeSet declaration should be as follows:

    TreeSet a = new TreeSet();

  But TreeSet has a constructor that can pass in a comparator (anonymous inner class)

    public static void main(String[] args) {
        TreeSet a = new TreeSet(new Comparator() { //Anonymous Inner Class 
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).compareTo((String)o2); //Compare by string size
            }
        });
        a.add("jack");
        a.add("a");
        a.add("sss");
        a.add("mmm");
        System.out.println(a);// [a, jack, mmm, sss]
    }

  One problem to note: suppose you want to sort from small to large according to the length of the string

    public static void main(String[] args) {
        TreeSet a = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length(); //from small to large
            }
        });
        a.add("jack");
        a.add("a");
        a.add("sss");
        a.add("mmm");
        System.out.println(a); // [a, sss, jack]
    }

  It can be found that "mmm" is not added, so we need to catch up with the source code.

        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        } // Initialize and generate a new node
        int cmp;
        Entry<K,V> parent;
        Comparator<? super K> cpr = comparator; //The point here is to assign the comparator to the past
        if (cpr != null) {
            do {   //Cycle the entire linked list (key) to find the appropriate position for the current key
                parent = t;
                cmp = cpr.compare(key, t.key); //Compare the key s of the original node and the node to be added
                                               //This will be dynamically bound to anonymous inner class objects
                if (cmp < 0) 
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;  //Move the pointer according to the comparison result
                else  //During the traversal, it is found that the key to be added is equal to the existing key
                    return t.setValue(value); //Since the value of Set is PRESENT, it is equivalent to not adding
            } while (t != null); //After the loop ends, t points to the position where the node should join
                                 //The parent is the last time, so it needs to be moved again after the end
        }
        ... //Without comparator
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e; //Put node e in the correct position according to the comparison results (parent is the original t)
        fixAfterInsertion(e);
        size++; //Number of nodes plus one
        modCount++; //Number of modifications plus one
        return null;
    }

    "sss" is added first, with a length of 3. Because the custom comparator compares the length, and   The length of "mmm" is also 3, so the result is 0. It is not added directly (refer to else in do).

    Since the bottom layer of TreeSet is TreeMap, the comparator initialization method is in TreeMap.

    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }

  TreeMap is the bottom layer of TreeSet and TreeMap, so the source code of TreeMap is no longer parsed.

Collections

Methods (all static)  

    public static void main(String[] args) {
        List a = new LinkedList();
        a.add("Tom");
        a.add("king");
        a.add("milan");
        Collections.reverse(a);
        System.out.println(a); //[milan, king, Tom]
        Collections.shuffle(a);
        System.out.println(a); //[Tom, king, milan]
        Collections.sort(a);
        System.out.println(a);//[Tom, king, Milan] (M > k > t) compare with the size of the string
        Collections.sort(a, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length(); //From small to large according to length
            }
        });
        System.out.println(a); //[Tom, king, milan]
        Collections.swap(a,0,2);
        System.out.println(a); //[milan, king, Tom]
    }

  Note that the parameter location of the copy method and the error will be reported if the memory is insufficient.  

    public static void main(String[] args) {
        List a = new LinkedList();
        a.add("Tom");
        a.add("king");
        a.add("milan");
        Object max = Collections.max(a); //The return value is an Object
        System.out.println(max); //milan string Max
        Object max2 = Collections.max(a, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println(max2);//milan, maximum length
        System.out.println(Collections.frequency(a,"Tom"));//1
        List b = new LinkedList();
        // Collections.copy(b,a);  Error: B has no memory space at this time
        //The following is copied. According to the source code, an exception will be thrown if a.size > b.size
        for(int i = 0;i<5;i++){
            b.add("");
        }  //Expand b's memory
        Collections.copy(b,a);
        System.out.println(b); //[Tom, king, milan,] the remaining two are ""
        Collections.replaceAll(a,"Tom","Jack");
        System.out.println(a); //[Jack, king, milan]
    }

 

Topics: Java