1. ArrayList Do you know ? Whatizit ? What's the use ?
as everyone knows ,Java The collection framework has two interfaces Collection and Map, among ,Collection His three sons List、Set and Queue.ArrayList And that's what happened List Interface , It's actually an array list , However, as Java The collection framework of , It can only store object reference types , In other words, when we need to load data such as int、float Waiting for the basic data type , They have to be converted to the corresponding wrapper class .
ArrayList The underlying implementation of is a Object Array :

Since it's based on arrays , Arrays are allocated consecutively in memory space , It must be very fast , But of course, it can't escape the defect of low efficiency of addition and deletion .
in addition , and ArrayList The same has been achieved List Interface 、 We also use LinkedList.LinkedList A special , It not only realizes List Interface , It's also achieved Queue Interface , So you can see LinkedList Often used as a queue :
Queue<Integer> queue = new LinkedList<>();
LinkedList A man is his name , Its bottom layer is naturally based on linked lists , And it's a two-way linked list . The properties of a linked list and an array are just the opposite , Because there is no index , So the query efficiency is low , But it's fast to add and delete .

2. ArrayList How to specify the size of the underlying array ?
OK, First , Since the place where we really store data is array , Let's initialize ArrayList It's natural to assign a size to the array , Open up a memory space . Let's take a look first ArrayList The parameterless constructor for :

You can see , It's for the bottom Object An array is just elementData Assigned a default empty array DEFAULTCAPACITY_EMPTY_ELEMENTDATA. in other words , Initialization using a parameterless constructor ArrayList after , It had an array capacity of 0 .
This initializes us with a capacity of 0 What's the use of arrays of ? I can't save anything ? Don't worry. , If you use a parameterless constructor to initialize ArrayList, Only when we really add data add when , Will assign a default initial capacity to the array DEFAULT_CAPACITY = 10. Look at the picture below :

That's it. Nonparametric construction ,ArrayList The parameterized constructors of are in order , Open up the array space according to the size passed in by the user :

3. The size of an array cannot be changed once it is specified , that ArrayList How to expand the underlying array ?
ArrayList The underlying implementation of Object Array , We know , The size of an array cannot be changed once it is specified . If we keep adding data to it ,ArrayList How to expand the capacity ? Or say ArrayList How to store any number of objects ?
OK, When did the expansion take place ? That must be when we add a new element to the array, but find that the array is full . you 're right , Let's go to the add Look at the method ArrayList How to expand the capacity :

ensureExplicitCapacity Whether it needs to be expanded , Obviously ,grow Method is the key to capacity expansion :

Tell the truth , I don't have to look at anything else , Just look at the yellow box in the picture above ArrayList How to expand the capacity : The length of the expanded array = Current array length + Current array length / 2. Finally using Arrays.copyOf Method to put the array in the original array directly copy To come over , It should be noted that ,Arrays.copyOf Method creates a New array And then copy it .
For example, draw a picture to illustrate :

4. Since the expansion happened when the data was added , Tell me about ArrayList How to add data
OK,add We've just talked about half the way , Before adding data, we will first determine whether we need to expand the capacity , The real operation of adding data is in the second half :

Let's talk about add(int index, E element) The meaning of this method , It's in the specified index index Insert element at element. for instance ArrayList.add(0, 3), It means inserting elements in the head 3.
Look again. add The core of the method System.arraycopy, This method has 5 Parameters :
- elementData: Source array
- index: Copy from where in the source array
- elementData: Target array
- index + 1: Copy to which position in the target array
- size - index: The number of array elements in the source array to copy
Explain the code above arraycopy It means , for instance , We want to index = 5 The location of the insert element , First , We'll copy the source array elementData( Here we call the copied array the new array ), And then take the source array from index = 5 From the beginning to the end of the array , Put it in the new array index + 1 = 6 Location :

therefore , This makes room for the elements we want to add , And then in the new array index = 5 Put the element in the position of element The operation of adding is completed :

obviously , Needless to say ,ArrayList The performance of inserting data into the specified location is very poor , Because we need to open up a new array to copy elements , When it comes to capacity expansion, it's even slower .
in addition ,ArrayList There's also a built-in... That adds elements directly to the end add Method , You don't have to copy arrays , direct size ++ Just fine , This method should be the one we use most often :

5. ArrayList How to delete data ?
Ctrl + F find remove Method , Is this ? And add a reason , It's also a copy array

for instance , Let's say we're going to delete the array index = 5 The elements of , First , We'll copy the source array , And then take the source array from index + 1 = 6 From the beginning to the end of the array , Put it in the new array index = 5 Location :

in other words index = 5 It's covered up directly , It gives you the feeling of being deleted . alike , Its efficiency is also very low
6. ArrayList Is it thread safe ? Unsafe performance
ArrayList and LinkedList It's not thread safe , Let's add the element at the end add Methods as an example , Let's see ArrayList What is the manifestation of thread insecurity :

It's not an atomic operation in the yellow box , It consists of two steps :
elementData[size] = e;
size = size + 1;
When these two pieces of code are executed in a single thread , Of course, there's no problem , But when executed in a multithreaded environment , It could happen Values added by one thread override values added by another thread . for instance :
- hypothesis size = 0, We're going to add elements to the end of this array
- Threads A Start adding an element , The value is A. At this point it performs the first operation , take A Put it in the array elementData Subscript to be 0 Location
- Then thread B Just start adding a value of B The elements of , And went to the first step of operation . The thread B Acquired size The value is still 0, So it will B It's on elementData Subscript to be 0 Location
- Threads A Began to increase size Value ,size = 1
- Threads B Began to increase size Value ,size = 2
such , Threads A、B When it's all done , The ideal would be size = 2,elementData[0] = A,elementData[1] = B. And the reality is size = 2,elementData[0] = B( Threads B Covered threads A The operation of ), Subscript 1 There's nothing in my position . And then unless we use set Method change the subscript to 1 Value , Otherwise this position will always be null, Because when you add an element at the end, it will start from size = 2 Starting from the position of .
The last part of the code verification :

The results are the same as what we analyzed :

ArrayList The thread safe version of is Vector, Its implementation is very simple , It's to add all the methods synchronized :

Since it requires extra overhead to maintain the synchronization lock , So theoretically, it's better than ArrayList slower .
7. Why use it when threads are not safe ?
Because in most scenes , Most of the queries are , It won't involve too frequent additions and deletions . If it really involves frequent additions and deletions , have access to LinkedList, The underlying linked list implementation , Created for addition and deletion . And if you have to be thread safe, use Vector. Of course, the most used in the actual development is ArrayList, Although threads are not safe 、 The efficiency of addition and deletion is low , But the query efficiency is high .
Hello, guys , I'm veal , official account 【 Flying veal 】 Regularly push interview questions from large factories , Provide recitation version + A detailed version , You know what you're doing and you know what you're doing , Make the eight part essay valuable !)







