Java collection and underlying source code analysis, introduction to Java zero foundation pdf

Posted by phaseonemedia on Sat, 20 Nov 2021 01:07:23 +0100

  1. If the hash value corresponding to the element at the index position is the same as the hash value of the element to be inserted, and it is the same reference or content, it cannot be added

  2. If the index position has a value and satisfies a red black tree, call the algorithm of the red black tree to add

  3. If the index position has a value and is a linked list, the linked list is compared circularly. If there are the same elements, they are not allowed to be added, otherwise they can be added to the end of the chain

//1. Execute HashSet()

   public HashSet() {

        map = new HashMap<>();

    }

//2. Execute add()

    public boolean add(E e) {

            return map.put(e, PRESENT)==null;

        }

//3. Execute put()

 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);//Unsigned right shift 16 bits of hash value to prevent conflict

    }

//4. Execute putVal()

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,

                   boolean evict) {

        Node<K,V>[] tab; Node<K,V> p; int n, i;

        //tab is actually an array of HashMap. The type is Node []. It is expanded to 16 spaces for the first time

        if ((tab = table) == null || (n = tab.length) == 0)

            n = (tab = resize()).length;

        //Get a hash value according to the key, then calculate the index subscript corresponding to the key in the tab, and assign the element corresponding to the index to p

        //if p == null, it means that there is no element stored in this location, so a Node will be created

        if ((p = tab[i = (n - 1) & hash]) == null)

            tab[i] = newNode(hash, key, value, null);

        else {

            Node<K,V> e; K k;

            //Judge whether the references or contents of the currently added objects are the same, provided that their hash values are the same. If the conditions are met, they will not be added

            if (p.hash == hash &&

                ((k = p.key) == key || (key != null && key.equals(k))))

                e = p;

                //Otherwise, judge whether it is a red black tree. If it is a red black tree, use the algorithm of red black tree

            else if (p instanceof TreeNode)

                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);

            else {

            //Otherwise, if it is a linked list, it will be compared circularly in turn. If the same one is found, it will exit. Otherwise, the current object can be placed at the end

                for (int binCount = 0; ; ++binCount) {

                    if ((e = p.next) == null) {

                        p.next = newNode(hash, key, value, null);

                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st

                            treeifyBin(tab, hash);

                        break;

                    }

                    if (e.hash == hash &&

                        ((k = e.key) == key || (key != null && key.equals(k))))

                        break;

                    p = e;

                }

            }

            if (e != null) { // existing mapping for key

                V oldValue = e.value;

                if (!onlyIfAbsent || oldValue == null)

                    e.value = value;

                afterNodeAccess(e);

                return oldValue;

            }

        }

        ++modCount;

        if (++size > threshold)

            resize();

        afterNodeInsertion(evict);

        return null;

    } 

[](

)LinkedHashSet

The underlying layer of LinkedHashSet is a LInkedHashMap, and the underlying layer maintains an array + two-way linked list

The LInkedHashSet determines the position of elements according to the HashCode value of elements, and uses the linked list to maintain the order of elements, which makes the elements appear to be saved in the order of insertion

LInkedHashSet does not allow adding duplicate elements

[](

)Map collection

Map and Collection exist side by side. Used to save data with mapping relationship: key value

The key and value in the Map can be data of any reference type and will be encapsulated in the HashMap $Node object

The key in the Map cannot be repeated for the same reason as the HashSet. The source code has been analyzed earlier, and the value in the Map can be repeated

The key and value of Map can be null. Note that there can be only one key and multiple values

String class is often used as the key of Map, but not all can only use string as the key. There is a one-way one-to-one relationship between kev and value, that is, the corresponding value can always be found through the specified kev

The k-v form will eventually be HashMap $Node node = newNode(hash, key,value,null)

k-v to facilitate the programmer's traversal, it also creates an EntrySet set, which stores the type of element entry, and an entry object has k,v, EntrySet < entry < k,v > >, that is, transient set < map. Entry < k,v > > EntrySet;

In the entrySet, the defined type is Map.Entry, but the HashMap $Node is actually stored

This is because static class node < K, V > implements map. Entry < K, V >, when the HashMap $Node object is stored in the entrySet, it is convenient for us to traverse

[](

)Traversal mode of Map interface

  1. Get all the keys in the map through the keySet, and return a collection after obtaining the keys. You can use the collection traversal enhancement for or iterator for traversal

  2. Get all value sets through values, which can be traversed through the set

  3. Get all relationships k-v through entrySet, which can be traversed through the set

[](

)HashMap

The underlying layer of HashMap maintains an array table of Node type, which is null by default

When creating an object, initialize the load factor to 0.75

When adding key val, the index in the table is obtained through the hash value of the key. Then judge whether there are elements at the index. If there are no elements, add them directly. If there is an element in the index, continue to judge whether the key of the element is consistent with the key to be added. If it is equal, directly replace val; If it is not equal, you need to judge whether it is a tree structure or a linked list structure and deal with it accordingly. If it is found that the capacity is insufficient when adding, it needs to be expanded.

For the first addition, the capacity of the table needs to be expanded. The capacity is 16 and the threshold is 12 (16 * 0.75)

For subsequent capacity expansion, the capacity of the table needs to be doubled (32), and the critical value is doubled (24). And so on

In Java 8, if the number of elements in a linked list exceeds tree_ Threshold (8 by default), size of table > = min_ TREEIFY_ Capability (64 by default) will be trealized (red black tree)

Source code analysis and conclusion

The same as HashSet, because the bottom layer of HashSet is HashMap

[](

)Hashtable

The stored elements are key value pairs: K-V

The key and value of hashtable cannot be null, otherwise NullPointerException3) hashTable is basically used in the same way as HashMap

hashTable is thread safe and HashMap is thread unsafe

Source code analysis and conclusion:

  1. The underlying maintenance of Hashtable is also an array. The initialization size of Hashtable$Entry [] is 11

  2. The critical value is equal to 11 * 0.75 = 8

  3. Capacity expansion mechanism: when the added quantity reaches the critical value, the capacity expansion is twice the original + 1, that is: newcapacity = (oldcapacity < < 1) + 1;

  4. When the value corresponding to the same key is added, the value is replaced

 private void addEntry(int hash, K key, V value, int index) {

        modCount++;



        Entry<?,?> tab[] = table;

        if (count >= threshold) {

            // Rehash the table if the threshold is exceeded

            rehash();



            tab = table;

            hash = key.hashCode();

            index = (hash & 0x7FFFFFFF) % tab.length;

        }



        // Creates the new entry.

        @SuppressWarnings("unchecked")

        Entry<K,V> e = (Entry<K,V>) tab[index];

        tab[index] = new Entry<>(hash, key, value, e);

        count++;

    }



    protected void rehash() {

        int oldCapacity = table.length;

        Entry<?,?>[] oldMap = table;



        // overflow-conscious code

        int newCapacity = (oldCapacity << 1) + 1;//Capacity expansion mechanism

        if (newCapacity - MAX_ARRAY_SIZE > 0) {

            if (oldCapacity == MAX_ARRAY_SIZE)

                // Keep running with MAX_ARRAY_SIZE buckets

                return;

            newCapacity = MAX_ARRAY_SIZE;

        }

        Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];



        modCount++;

        threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);

        table = newMap;



        for (int i = oldCapacity ; i-- > 0 ;) {

            for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {

                Entry<K,V> e = old;

                old = old.next;



                int index = (e.hash & 0x7FFFFFFF) % newCapacity;

                e.next = (Entry<K,V>)newMap[index];

                newMap[index] = e;

            }

        }

    } 

Comparison between Hashtable and HashMap:

|| version | thread safety (synchronization) | efficiency | allow null key and null value|

| :-: | :-: | :-: | :-: | :-: |

|Hashtable | 1.0 | security | not high | not allowed|

|HashMap | 1.2 | unsafe | high | allowed|

[](

)Properties

  1. The Properties class inherits from the Hashtable class and implements the Map interface. It also uses a key value pair

    Formula to save data. Its use characteristics are similar to Hashtable

  2. Properties can also be used to load data into the properties class object from the xxx.properties file,

    And sell and modify

Relevant knowledge points: https://www.cnblogs.com/xudong-bupt/p/3758136.html

[](

)TreeSet

The bottom layer of TreeSet is actually TreeMap

Sortable (the output can be sorted in a user-defined way. The bottom insertion order is the same as the extraction order, not the order of add, but the order calculated by the comparator)

Source code analysis and conclusion:

  1. When an object is created using parameterless construction, the key will be converted into a comparator object by default (provided that the key must implement Comparable and compareTo method), and the default compareTo method will be used for natural sorting

  2. When using parametric construction, you need to pass in a comparator object containing the compare method, and then the bottom layer of TreeSet will encapsulate it to the comparator in the TreeMap object. If the bottom layer is added, it will automatically call this method for sorting

  3. If the TreeSet stores Integer objects, the default sorting method is small to large;

  4. If the TreeSet stores String objects, the default sorting method is to compare the first letter of the String and sort by the size of Unicode values;

  5. If the TreeSet stores custom classes; If the comparator is not specified, an exception will be reported;

 public V put(K key, V value) {

        Entry<K,V> t = root;

        if (t == null) {

            compare(key, key); // type (and possibly null) check / / the comparison is called when adding for the first time to judge whether the comparison can be performed



            root = new Entry<>(key, value, null);

            size = 1;

            modCount++;

            return null;

        }

        int cmp;

        Entry<K,V> parent;

        // split comparator and comparable paths

        Comparator<? super K> cpr = comparator;

        if (cpr != null) {

            do {

                parent = t;

                cmp = cpr.compare(key, t.key);//The passed in comparator object contains a custom compare method

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

                else

                    return t.setValue(value);

            } while (t != null);

        }

        else {

            if (key == null)

                throw new NullPointerException();

            @SuppressWarnings("unchecked")

                Comparable<? super K> k = (Comparable<? super K>) key;//The default comparison method is provided that the key must implement the Comparable interface

            do {

                parent = t;

                cmp = k.compareTo(t.key);

                if (cmp < 0)

                    t = t.left;


> **Java Network disk: pan.baidu.com/s/1MtPP4d9Xy3qb7zrF4N8Qpg
> Extraction code: 2 p8n**



# summary

Here, due to the interview MySQL I asked a lot, so I'm here MySQL Take as an example to summarize and share. But you often have to learn more than this, as well as the use of some mainstream frameworks, Spring Learning the source code, Mybatis The learning of source code and so on need to be mastered, and I have sorted out these knowledge points

**[CodeChina Open source project: [first tier big factory] Java Analysis of interview questions+Core summary learning notes+Latest explanation Video]](

)**

![Interview questions](https://img-blog.csdnimg.cn/img_convert/23ceb5f8d8d05ba5d8f81d4b89976d3f.png)


uper K> k = (Comparable<? super K>) key;//The default comparison method is provided that the key must implement the Comparable interface

            do {

                parent = t;

                cmp = k.compareTo(t.key);

                if (cmp < 0)

                    t = t.left;


> **Java Network disk: pan.baidu.com/s/1MtPP4d9Xy3qb7zrF4N8Qpg
> Extraction code: 2 p8n**



# summary

Here, due to the interview MySQL I asked a lot, so I'm here MySQL Take as an example to summarize and share. But you often have to learn more than this, as well as the use of some mainstream frameworks, Spring Learning the source code, Mybatis The learning of source code and so on need to be mastered, and I have sorted out these knowledge points

**[CodeChina Open source project: [first tier big factory] Java Analysis of interview questions+Core summary learning notes+Latest explanation Video]](

)**

[External chain picture transfer...(img-Iqgk3IB7-1631407615946)]


![Spring Source notes](https://img-blog.csdnimg.cn/img_convert/85b25b0078d456e15f8c6a234c15f1a3.png)

Topics: Java data structure Back-end Programmer linked list