Java collection -- implementation classes of Map interface HashMap, LinkHashMap, TreeMap and Properties

HashMap class

1. HashMap class overview

HashMap is the most frequently used implementation class of Map interface, which allows the use of null keys and null values. Like HashSet, the mapping order is not guaranteed.

The Set composed of all keys is Set: unordered and non repeatable. Therefore, the class where the key is located should be overridden
equals() and hashCode().
The Collection of all values is a Collection: unordered and repeatable. Therefore, the class where value is located
To override equals().

A key value constitutes an entry, and the Set of all entries is Set: disordered and non repeatable.

HashMap judges the equality of two keys: two keys return true through the equals() method,
The hashCode() value is also equal.
HashMap judges the equality of two values: the two values return true through the equals() method.

2. Storage structure of HashMap (underlying implementation principle)

HashMap map = new HashMap()

(described in JDK1.7)
After instantiation, the bottom layer creates a one-dimensional array Entry[] table with a length of 16.

map.put(key1,value1)

First, call hashCode() of the class where key1 is located to calculate the hash value of key1. After the hash value is calculated by some algorithm, the storage location in the Entry [] array is obtained.

If the data in this location is empty, key1-value1 is added successfully---- Case 1
If the data in this location is not empty (which means that there are one or more data in this location (in the form of linked list)), continue to compare the hash values of key1 and one or more existing data:

If the hash value of key1 is different from the hash value of existing data, key1-value1 is added successfully---- Case 2
If the hash value of key1 is the same as the hash value of an existing data key2-value2, continue the comparison:

Call equals(key2) of the class where key1 is located
If equals() returns false: key1-value1 is added successfully---- Case 3
If equals() returns true: replace value2 with value1.

Supplement: for case 2 and case 3, key1-value1 and the original data are stored in a linked list.
During the continuous addition process, the problem of capacity expansion will be involved. The default capacity expansion method is to double the original capacity and copy the original data.

JDK1.8 is different from JDK1.7 in terms of underlying implementation:
① new HashMap(), the underlying layer has not created an array with a length of 16
② The underlying array of JDK1.8 is: Node [], not Entry []
③ When the put() method is called for the first time, the underlying layer creates an array Node [] with a length of 16
④ When forming a linked list structure, the newly added key value pair is at the end of the linked list (seven up and eight down)
⑤ The underlying structure of JDK1.7 is only "array + linked list", and the underlying structure of JDK1.8 is "array + linked list + red black tree".
When the number of data in the form of linked list of elements at an index position of the array is > 8 and the length of the current array is > 64, all data at this index position will be stored in red black tree instead.


3. Important constants in HashMap source code

DEFAULT_ INITIAL_ Capability: default capacity of HashMap, 16
MAXIMUM_ Capability: maximum supported capacity of HashMap, 2 ^ 30
DEFAULT_LOAD_FACTOR: default load factor of HashMap, 0.75
TREEIFY_THRESHOLD: if the length of the linked list in the Bucket is greater than the default value of 8, it will be converted into a red black tree
UNTREEIFY_THRESHOLD: if the Node stored in the red black tree in the Bucket is less than the default value of 6, it is converted into a linked list
MIN_ TREEIFY_ Capability: the minimum hash table capacity when the nodes in the bucket are trealized. (when the number of nodes in the bucket is so large that the tree needs to be reddened and black, if the capacity of the hash table is less than min_tree_capacity, the resize expansion operation should be performed at this time. The value of min_tree_capacity is at least 4 times that of tree_threshold, which is 64.)
table: an array of storage elements, always to the nth power of 2
entrySet: a set that stores concrete elements
size: the number of key value pairs stored in the HashMap
modCount: the number of HashMap expansion and structure changes.
threshold: critical value of expansion, = capacity * filling factor
loadFactor: fill factor

LinkedHashMap class

LinkedHashMap is a subclass of HashMap

Based on the HashMap storage structure, a pair of two-way linked lists are used to record the order of adding elements

Similar to LinkedHashSet, LinkedHashMap can maintain the iteration order of Map: the iteration order is consistent with the insertion order of key value pairs

TreeMap class

1. TreeMap class overview

When storing key value pairs in TreeMap, you need to sort by key. TreeMap can ensure that all key values are in an orderly state.

The underlying TreeSet uses a red black tree structure to store data.

Sorting of TreeMap keys:
① Natural sorting: all keys of TreeMap must implement the Comparable interface, and all
The Key of should be an object of the same class, otherwise ClasssCastException will be thrown.
② Custom sorting: when creating a TreeMap, a Comparator object is passed in, which is responsible for sorting
All keys in the TreeMap are sorted. At this time, it is not necessary to implement the Comparable interface for the keys of the Map.

TreeMap judges the equality of two keys: two keys return 0 through the compareTo() method or the compare() method.

2. Natural sorting

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * @Author: Yeman
 * @Date: 2021-09-22-22:59
 * @Description:
 */

class user implements Comparable{
    String name;
    int age;

    public user(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "user{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof user){
            user other = (user) o;
            Integer nameResult = this.name.compareTo(other.name);
            if (nameResult == 0){
                return Integer.compare(this.age,other.age);
            }else return nameResult;
        }else throw new RuntimeException("type mismatch");
    }
}


public class TreeMapTest {
    public static void main(String[] args) {
        Map map = new TreeMap();
        map.put(new user("Tom",22),1);
        map.put(new user("Jim",18),2);
        map.put(new user("Marry",20),3);
        map.put(new user("Lily",16),4);
        map.put(new user("Tom",18),5);

        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

3. Custom sorting

import java.util.*;

/**
 * @Author: Yeman
 * @Date: 2021-09-22-22:59
 * @Description:
 */

class user {
    String name;
    int age;

    public user(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "user{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class TreeMapTest {
    public static void main(String[] args) {
        Comparator comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof user && o2 instanceof user) {
                    user user1 = (user) o1;
                    user user2 = (user) o2;
                    Integer nameResult = user1.name.compareTo(user2.name);
                    if (nameResult == 0) return Integer.compare(user1.age, user2.age);
                    else return nameResult;
                } else throw new RuntimeException("type mismatch");
            }
        };

        Map map = new TreeMap(comparator);
        map.put(new user("Tom",22),1);
        map.put(new user("Jim",18),2);
        map.put(new user("Marry",20),3);
        map.put(new user("Lily",16),4);
        map.put(new user("Tom",18),5);

        Set set = map.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

Hashtable class

Hashtable is an ancient Map implementation class, which is provided by JDK1.0. Unlike HashMap,
Hashtable is thread safe.

The implementation principle and function of Hashtable are the same as that of HashMap. The bottom layer uses hash table structure to query
It is fast and can be used with each other in many cases.

Unlike HashMap, Hashtable does not allow null as key and value.
Like HashMap, Hashtable cannot guarantee the order of key value pairs.

Hashtable judges that two key s are equal and two value s are equal, which is consistent with HashMap.

Properties class

The Properties class is a subclass of Hashtable. This object is used to process the property file. Since the key and value in the property file are of string type, the key and value in Properties are of string type

When accessing data, it is recommended to use setProperty(String key,String value) method and getProperty(String key) method

Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);

Tags: Java HashMap map treemap

Posted on Wed, 22 Sep 2021 12:56:42 -0400 by ToeBee