The review week has begun, and the summary about the collection is here

1. Collection

1、List、Set、HashMap

Tell me about the difference between the three?

The elements stored in the List are ordered and repeatable

The elements stored in Set are unordered and cannot be repeated, and the elements cannot be empty

HashMap storage elements are stored in the form of Key-Value key-value pairs, the key and value can be empty

What are the implementation classes below them?

Let me talk about List first. The following implementation classes include:

  • ArrayList: Its underlying data structure is an array, and it is not thread-safe. Its expansion mechanism: expand to 1.5 times the original size, declare a position of 1.5 times the space, and copy the contents of the original array to this larger space
  • LinkedList: Its underlying data structure is a doubly linked list, and it is thread-unsafe.
  • vector: Its underlying data structure is an array, but it is thread-safe

Let’s talk about Set again. The following implementation classes include:

  • HashSet: It inherits HashMap at the bottom layer, and its elements are stored in the key of the HashMap at the bottom layer, which is why its value is required to be non-repetitive, and it is overwritten when it encounters duplicate values.
  • LinkedHashSet: LinkedHashSet is a subclass of HashSet, and the bottom layer is implemented through LinkedHashMap.
  • TreeSet: Red-black tree (a self-balanced sorting binary tree).

Finally, let’s talk about Map. The following implementation classes include:

  • HashMap: It is actually a hash table. Before jdk1.8, the bottom layer uses an array plus a linked list to store elements. Arrays are the theme of HashMap. Linked lists exist more to resolve Hash conflicts (using the zipper method to resolve hash conflicts) ), in jdk1.8, the bottom layer is to store elements in the form of an array plus a linked list plus a red-black tree. The reason for introducing the red-black tree is to prevent the linked list from being too long and reducing the retrieval efficiency.
  • TreeMap: Red-black tree, a sort of self-balancing binary tree
  • LinkedHashMap: LinkedHashMap inherits from HashMap, so its bottom layer is still an array and linked list structure based on a zipper hash table. The difference is that it adds a doubly linked list based on the above, this doubly linked list mainly maintains the insertion order of elements .
  • HashTable: This inherits the Dictionary class, which is composed of an array and a linked list. HashTable is thread-unsafe

Then tell me about HashMap, right?

At 8, this hash table added a red-black tree structure. When the length of the linked list is greater than 8, it will be converted to a red-black tree to improve the query efficiency of elements. It has four constructors, including a non-parameter constructor, a constructor that specifies the initial capacity, a constructor that specifies the initial capacity and load factor, and a constructor that wraps the Map. In fact, when specifying the initial capacity, you do not specify how much capacity is. , It will enter a tableForSize method after processing to return a power of 2 closest to itself that is larger than the current specified capacity as the initial capacity of the entire HashMap. The more important thing is that the put method and get method also have a resize method. Before talking about these methods, I will mention another function, which is the hash method. The AND operation is mainly done here. The hashcode value of the key of HashMap is high. The value obtained by the AND operation of the 16 bits and the lower 16 bits is returned, and this is used as the value of the hash attribute in the Node object. Come back to the get method, calculate its hash value by passing in the key, and then calculate the index according to the length of the Node array, find the hash of the key of the array head element corresponding to this index and whether the object is consistent with the passed key, if it is consistent , Return this element, and judge this if inconsistent Whether the head element has the next node, if there is a node, traverse downwards. According to the different instances of the head node, different traversal methods are used. During the traversal process, if there is no such element, it will return empty, and if there is, return this node. value. Let's talk about the put method. It is a method of inserting elements. It also calculates the index subscript based on the hash value and the length of the array, finds this subscript, and inserts it directly if there is no value. If there is a value, judges the head element If the key is the same as the key of the element to be inserted, if they are the same, directly overwrite the element. If they are different, judge the instance of this element. If it is a tree instance, insert the element according to the tree instance insertion method. If it is a linked list, just Traverse the linked list, and if it is determined that there is an element consistent with this element on the way, the value is overwritten, otherwise the element to be inserted is inserted at the end of the linked list. Let's talk about the resize method of expansion. This method is not only used for expansion, but also for initializing capacity. When the capacity is initialized, default values ​​are attached to its Wing Wolf and load factor. When expanding the capacity, we analyzed its source code and found that it did not re-hash, but used the original hash value to judge whether one of its bits was 0 or 1, and if it was 0, put it in the low-order linked list, which is 1. Put it in the high list. After the traversal is completed, the high-order linked list is placed under the high-order index of the new array, and the low-order linked list is placed under the low index of the new array. Finally, the expansion of HashMap is different between jdk1.7 and 1.8. 1.7 uses the head insertion method, 1.8 uses the tail insertion method, and the 1.7 head insertion method may cause an endless loop in the linked list when expanding. 1.8 The scenario of thread insecurity is reflected in the possibility of element loss when inserting elements.

Which collections are thread safe? What is not safe and how to solve it?

Our commonly used ArrayList, LinkedList, HashSet, HashMap, etc. are not thread-safe. You can replace them with thread-safe collections, or you can use methods under the Collections tool class to wrap these collections to ensure thread safety. But these are modified by synchronized, the performance will become much lower.

Furthermore, there are many containers under the JUC package, including ConcurrentHashMap, CopyOnWriteArrayList, etc. ConcurrentHashMap can be regarded as a thread-safe HashMap, and CopyOnWriteArrayList can be regarded as a thread-safe ArrayList. Its performance is much higher than that of vector, and it is suitable for occasions with more reading and less writing.

You mentioned ConcurrentHashMap earlier, can you talk about it?

The bottom layer of ConcurrentHashMap is a structure of array + linked list + red-black tree. It is thread-safe, and its thread-safety is realized by segmented lock before jdk1.8. Read without lock, write with lock, it maintains a segment array internally, and it locks the data under a certain index of this array. Instead of locking the entire hash table, this is much better than HashTable performance. It was changed in jdk1.8, the segment was removed, and optimized, and the head node was locked by synchronized + CAS spin to make the lock more Fine-grained, and further improve performance.

By the way, also talk about CopyOnWriteArrayList

It maintains a ReentrantLock at the bottom to ensure thread safety by displaying locks and unlocks when inserting elements.

2. What is fast failure and safe failure

Fast-fail: It is an error detection mechanism of Java collections. When we are iterators traversing the collection, we may trigger fast-fail when operating those collections that fail safely under multithreading, throwing ** ConcurrentModificationException** exceptions.

Safe-fail: This exception will not be thrown in the above scenario.

Guess you like

Origin blog.csdn.net/MarkusZhang/article/details/107918808