In-depth analysis of Java collections - covering high-frequency interview questions

1 Introduction

The article is a bit long, and it mainly talks about some underlying principles of collections. It basically includes the high-frequency interview questions in the current stereotyped essays. I hope you have the patience to read it, and you can communicate in the comment area.

2. The difference between an array and a collection

Declare the array:

//数据类型[] 数组名
int[] array = {
    
    1,2,3,4};
int[] array = new int[4];

Here we declare an int type array, then the data elements inside are fixed to be int type, and the size of the array is fixed.

Create a collection: Let's take List as an example

List list = new ArrayList();
list.add(1);
list.add("abc");

As you can see, a collection is an element that can hold different data types, and there is no fixed capacity size.

Summary: The array must declare the data type, an array can only store the same data type, and the capacity of the array is fixed, once declared it cannot be changed. Collections can store data of different data types, and will automatically expand.

3. Two camps of assembly

Collections are divided into Collection single-column collections and Map double-column collections. Collections are further divided into List (ordered and repeatable) and Set (unordered and non-repeatable).
insert image description here

4. Common methods in Collection

  • boolean add(E e) add element
  • boolean addAll(Collection<? extends E> c) Add a collection to it
  • void clear() deletes all elements
  • boolean contains(Object o) Determine whether to contain elements
  • boolean isEmpty() to determine whether it is empty
  • Iterator iterator() The iterator traverses the collection
  • boolean remove(Object o) remove the specified element
  • int size() the number of elements
  • Object[] toArray() collection to array

4.1 List family

The List collection is characterized by order and can store duplicate data

4.1.1 ArrayList source code analysis and interview focus

ArrayList: The bottom layer is a dynamic array, which is not thread-safe and supports fast random access, but its deletion and insertion efficiency is low. Compared with arrays, ArrayList can be expanded to store different types of data.

  • Empty parameter constructor initialization: new ArrayList();

jdk1.6 source code analysis:
insert image description here
insert image description here
look at the source code of added elements:
insert image description here
let's take a look at the method of ensuring capacity, which includes the expansion mechanism that is often asked in interviews!
insert image description here

Analysis and summary of jdk1.6 source code: no parameter constructor, the initial capacity is 10, when the capacity is not enough, expand the capacity by 1.5 times + 1, the expansion will copy the old array to the new array, and the capacity of the new array is the expanded capacity.

jdk1.8 source code analysis
insert image description here
Let's take a look at the method of adding elements

insert image description here
insert image description here
insert image description here
insert image description here
insert image description here

Summary of jdk1.8 source code analysis: The no-argument constructor initializes an empty array without specifying the capacity. When adding elements for the first time, the capacity is 10. If the capacity is expanded later, the capacity will be expanded by 1.5 times.

Summary: There are two differences between ArrayList 1.8 and 1.6. One is that the initial capacity is not specified during initialization, and the second is that the expansion is no longer 1.5 times + 1, but 1.5 times.

4.1.2 Common methods

  • boolean add(E e)
  • add(int index, E element) Add an element at the specified position
  • forEach(Consumer<? super E> action) traversal
  • get(int index) Get the element according to the subscript
  • indexOf(Object o) Get the subscript of the specified element
  • isEmpty() returns true if this list contains no elements
  • iterator() traverse
  • lastIndexOf(Object o) Get the last occurrence position of the specified element
  • toArray() converts to an array
  • size() the number of elements in the collection

4.1.3 Difference between ArrayList and LinkedList

The bottom layer of ArrayList is a dynamic array, and the query efficiency is higher than that of LinkedList. The bottom layer of LinkedList is a doubly linked list, and the efficiency of inserting and deleting elements in the middle is higher than that of ArrayList.

4.2 Set family

The characteristics of the Set collection: unordered, non-repeatable

4.2.1 HashSet

The bottom layer is a hash table (array + linked list + red-black tree), which stores elements that are unordered and non-repeatable, and can store a unique null value.

  • Why is it unordered?

When HashSet adds elements, it will calculate the storage location according to the hashcode of the added elements, so it is not stored according to the order you store, but according to the hashcode.

  • So why is it not repeatable?

When the elements have the same hashcode, the second element is bound to be at the same position as the same element. At this time, the equals method is called. If they are also the same, the same element will be overwritten. If not, add a node to the linked list structure of the node.
Therefore, when using HashSet, the hashcode and equals must be rewritten for the stored elements.

4.2.2 TreeSet

The bottom layer is implemented based on TreeMap, which is characterized by order and non-repeatability.

  • Natural sorting: implement the Comparable interface and rewrite the compareTo method
  • Custom sorting: When creating a TreeMap object, pass in a Comparator interface and implement the compare method inside
public class TreeSetTest {
    
    
    public static void main(String[] args) {
    
    
        TreeSet<User> set = new TreeSet<>(new Comparator<User>() {
    
    
            @Override
            public int compare(User o1, User o2) {
    
    
                int i = o1.getName().compareTo(o2.getName());
                if(i==0){
    
    
                    return o1.getAge()-o2.getAge();
                }
                return i;
            }
        });

        set.add(new User("eason",23));
        set.add(new User("bill",24));
        set.add(new User("jame",17));
        set.add(new User("jame",18));
        Iterator<User> iterator = set.iterator();
        while (iterator.hasNext()){
    
    
            System.out.println(iterator.next());
        }
    }
}

5. Map family

5.1 HashMap

First of all, hashmap is not thread-safe. Both its key and value can be null, but only one null key is allowed.

5.1.1 Data structure

  • Before jdk1.8,
    the underlying data structure is an array + linked list, the array is the main body of the HashMap, and the linked list is mainly to solve the hash collision (the hash values ​​​​calculated by the hashCode method called by the two objects are consistent, resulting in the same calculated array index value) and exists ("zipper method" for conflict resolution).
  • The underlying data structure of jdk1.8
    is an array + linked list + red-black tree. When the length of the linked list is greater than 8 and the length of the current array is greater than 64, all data at this index position will be stored in a red-black tree. The purpose is to improve efficiency.
    If the length of the linked list is greater than 8, but the length of the array is less than 64, the array will be expanded.

5.1.2 Stored data process

5.1.3 Expansion mechanism

5.2 HashTable

Thread safe, inefficient, not recommended.

5.3 TreeMap

5.4 ConcurrentHashMap

Guess you like

Origin blog.csdn.net/zhang0305/article/details/126722124