其他分享
首页 > 其他分享> > 不深入了解ArrayList,你好意思睡觉?

不深入了解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