不深入了解ArrayList,你好意思睡觉?
作者:互联网
[toc]
1、ArrayList简介
ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小。
2、ArrayList和LinkedList底层实现原理和区别
2.1、底层实现:
ArrayList基于动态数组实现;
LinkedList基于双向链表实现;
2.2、ArrayList扩容机制
当数据超出当前数组的内存范围,会先试着比较数据长度和数组长度的1.5倍的大小,如果1.5倍大于元素长度(小于的话,则创建一个长度为数据长度的数组),那么直接通过Arrays.copyOf得到一个新长度的数组,把原数据拷贝过去,释放掉旧的数组;
2.3、区别
1.ArrayList在内存中顺序存储;LinkedList在内存中散列存储
2.插入元素时ArrayList除了尾插都需要开辟新的内存空间来存储新数组;LinkedList可以很方便的插入到链表中的任意位置,只需要断开待插入位置的前后指针,新元素建立指针关系即可。
3.取元素时ArrayList只需要根据元素下标直接取出;LinkedList需要遍历链表取出相应的元素
4.删除元素时ArrayList删除掉相应元素后需要对数组进行一次迁移;LinkedList删除时只需要断开前后指针重新建立指针关系即可。
2.4、简单总结
ArrayList:适合都多写少
LinkedList:适合写多读少
3、ArrayList是否线程安全?如何实现一个线程安全的ArrayList?
ArrayListUnsafeDemo.java
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
public class ArrayListUnsafeDemo {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
final int temp = i;
new Thread(() -> {
strings.add(String.valueOf(temp));
}, String.valueOf(i)).start();
}
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(strings.size());
}
}
ArrayListSafeDemo.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class ArrayListSafeDemo {
public static void main(String[] args) {
List<String> strings = Collections.synchronizedList(new ArrayList<String>());
for (int i = 0; i < 1000; i++) {
final int temp = i;
new Thread(() -> {
strings.add(String.valueOf(temp));
}, String.valueOf(i)).start();
}
try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println(strings.size());
}
}
4、手写一个简易的ArrayList
package com.negen.share;
import java.util.Arrays;
/**
* @author :Negen
* @Date :Created in 18:11 2021/6/9
* @Description:实现一个简单的arraylist
* @Modified By:
* @Version: 1.0
*/
public class MyEasyArrayList<T> {
/**
* 数组默认容量
*/
private static final int DEAFAULT_CAPACITY = 10;
/**
* 存储数据的数组
*/
private Object[] elementData = {};
/**
* 数组当前已存入元素的大小
*/
private int currentSize = 0;
MyEasyArrayList(){
elementData = new Object[DEAFAULT_CAPACITY];
}
MyEasyArrayList(int capacity){
if (capacity <= 0){
throw new IllegalArgumentException();
}
elementData = new Object[capacity];
}
/**
* 末尾添加元素
* @param element
*/
void add(T element){
ensureCapacity();
elementData[currentSize++] = element;
}
/**
* 指定位置插入元素
* @param index
* @param element
*/
void add(int index, T element){
//判断插入的位置是否合法
if (index < 0 || index >= currentSize){
throw new IndexOutOfBoundsException();
}
ensureCapacity();
//后移元素
for (int i = currentSize; i > index; i--){
elementData[i] = elementData[i-1];
}
elementData[index] = element;
currentSize++;
}
/**
* 获取指定位置的元素
* @param index
* @return
*/
T get(int index){
if (index < 0 || index >= currentSize){
throw new IndexOutOfBoundsException();
}
return (T) elementData[index];
}
/**
* 获取当前元素的个数
* @return
*/
int size(){
return currentSize;
}
/**
* 删除指定位置的元素
* @param index
* @return
*/
T remove(int index){
if (index < 0 || index >= currentSize){
throw new IndexOutOfBoundsException();
}
T element = (T) elementData[index];
for (int i = index; i < currentSize - 1; i++) {
elementData[i] = elementData[i+1];
}
elementData[currentSize - 1] = null;
currentSize--;
return element;
}
/**
* 数组扩容
*/
private void ensureCapacity() {
if (currentSize == elementData.length){
int newCapacity = elementData.length + (elementData.length >> 1);
/* Object[] newElementData = new Object[newCapacity];
for (int i = 0; i < elementData.length; i++) {
newElementData[i] = elementData[i];
}
elementData = newElementData;*/
Object[] newElementData = Arrays.copyOf(elementData, newCapacity);
elementData = newElementData;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < currentSize; i++) {
sb.append(elementData[i].toString()+ "---");
}
return sb.toString();
}
public static void main(String[] args) {
MyEasyArrayList<String> stringMyEasyArrayList = new MyEasyArrayList<>(3);
stringMyEasyArrayList.add("zhangsan");
stringMyEasyArrayList.add("zhangsan1");
stringMyEasyArrayList.add("zhangsan3");
stringMyEasyArrayList.add(0,"0");
// stringMyEasyArrayList.add(0,"zhangsan3");
// System.out.println(stringMyEasyArrayList.remove(2));
System.out.println(stringMyEasyArrayList);
System.out.println(stringMyEasyArrayList.size());
}
}
标签:index,睡觉,ArrayList,elementData,int,好意思,new,currentSize 来源: https://blog.csdn.net/qq_36657751/article/details/117825652