In-depth analysis of ArrayList usage

insert image description here

1. What is ArrayList?

The ArrayList class is an array that can be dynamically modified. The difference from ordinary arrays is that it has no fixed size limit, and we can add or delete elements. ArrayList inherits from AbstractList and implements List interface.
insert image description here

insert image description here
We found that the ArrayList class is located in the java.util package and needs to be imported before use.

import java.util.ArrayList;

How ArrayList is defined:

ArrayList<E> arrayList = new ArrayList<E>();

This number E is a generic actual parameter type, which can only be a reference data type. We can pass whatever type of data the ArrayList wants to store.

List<E> list = new ArrayList<E>();

Because our ArrayList is inherited from List, we can use the parent class to accept subclass objects and transform upwards.

Two, the construction method of ArrayList

insert image description here
We found that ArrayList provides a total of three construction methods.
Construction method 1:
Construct an empty sequence table

        List<Integer> list = new ArrayList<>();

Construction method 2:
Construct a sequence table with a specified size of 5

        List<Integer> list = new ArrayList<>(5);

Construction method 3:
insert image description here
The input here is either its own type or a subclass type.
Construct a sequential list consistent with list2 elements here

        List<Integer> list2 = new ArrayList<>(5);
        List<Integer> list = new ArrayList<>(list2);

initial pit

List list = new ArrayList();

In this way, if the sequence table is initialized, no type is specified, and elements of any type can be stored in this way, which will pose a great security risk.

3. Common methods of ArrayList

common method

In my previous implementation sequence table, most of the methods have been implemented manually, and here I am explaining a few key points.
insert image description here
The remove method
ArrayList provides us with two remove methods,
insert image description here
one is to pass in the subscript to be deleted, and the other is the reference to be deleted.

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(8);
        list.remove(1);
        System.out.println(list);
    }

If we pass in an int type, then what we delete is the data of the subscript.
insert image description here

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(10);
        list.add(8);
        list.remove(new Integer(10));
        System.out.println(list);
    }

If we pass in a reference data type, the reference data in the sequence table will be deleted.
insert image description here
subList method

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println("截取之前的list:"+list);
        List<Integer> list1 = list.subList(1,3);
        list1.set(0,5);
        System.out.println("截取之后的list:"+list);
    }

insert image description here
Why after changing list1, the data of list also changed.
insert image description here
Because after the interception, the content is not copied to list1, but points to the same piece of content.

Traversing the ArrayList

method 1:

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for (int i = 0; i < list.size(); i++) {
    
    
            System.out.print(list.get(i)+" ");
        }
        System.out.println();
    }

Method 2:

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        for (Integer x:list) {
    
    
            System.out.print(x+" ");
        }
        System.out.println();
    }

Method 3:
Using Iterators
insert image description here

method effect
.next() Returns an iterator to write an element, updating the iterator state
.hasNext() Check if there are more elements in the collection
.remove() deletes the element returned by the iterator
public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        Iterator<Integer> it = list.listIterator();
        while (it.hasNext()) {
    
    
            System.out.print(it.next()+" ");
        }
        System.out.println();
    }

Remove elements using iterators

We remove elements of the set less than 3

public static void main(String[] args) {
    
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        Iterator<Integer> it = list.listIterator();
        while (it.hasNext()) {
    
    
            if(it.next() < 3) {
    
    
                it.remove();
            }
        }
        System.out.println(list);
    }

insert image description here
The remove method of an iterator can only delete the currently pointed element.

4. Expansion mechanism of ArrayList

List<Integer> list = new ArrayList<>();

A lot of information is saying that a collection is initialized in this way, and the default size is 10. Is this the case? Let's look at the source code step by step to find out.

insert image description here
We found that the current reference points to the latter reference.
insert image description here
We found that the reference here is a null reference, and the initial collection was an empty collection .
So how to expand?
Since our sequence table is empty, how to add it?
insert image description here
insert image description here
insert image description here
If it is constructed without parameters, pass a default size and the maximum value of the incoming size.
insert image description here
We can find that if it is greater than the size of the array, it will grow.
insert image description here
We can find that we calculate a new capacity and compare it with the size we passed in. If the new capacity is smaller than the size passed in, specify the current collection size as the size passed in. Otherwise, expand the collection size by 1.5 times.
insert image description here
But if the size of our 1.5 times expansion exceeds the specified range of 2147483639,
insert image description here
the system will report a memory overflow exception.

1. Check whether expansion is really needed, if it is to call grow to prepare for expansion
2. Estimate the size of the required storage capacity. The
initial estimate is to expand the capacity by 1.5 times.
If the size required by the user exceeds the estimated size by 1.5 times, the
actual expansion will be based on the size required by the user. Check whether the expansion can be successful before expansion, to prevent expansion failure caused by too large
3. Use copyOf for expansion

Guess you like

Origin blog.csdn.net/buhuisuanfa/article/details/126926645