ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

不深入了解ArrayList,你好意思睡觉?

2021-06-11 19:00:08  阅读:162  来源: 互联网

标签:index 睡觉 ArrayList elementData int 好意思 new currentSize


在这里插入图片描述[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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有