Tic商业评论

关注微信公众号【站长自定义模块】,定时推送前沿、专业、深度的商业资讯。

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

  • QQ空间
  • 回复
  • 收藏

java中的常见集合之ArrayList、LinkedList

zhangchenmin java 2020-11-13 14:57 2699人围观


      首先list和set集合都实现了同一个集合的顶级接口Collection,那么collection与collections有什么区别呢?Collection是一个集合接口,提供了对集合对象进行操作的通用接口方法。而collections则是集合类的一个工具类,提供了一系列的静态方法,包括对集合的排序、搜索及线程安全等操作。
       我们常见的list有LinkedList和ArrayList ,下面我们从底层数据结构与实现来分析一下各自的优缺点。
       1、ArrayList底层是一个基于索引object数组,查询时间复杂度为O(1),因为插入和删除时需要移动下标所以导致开销增大效率低下,在JDK1.7及之前,初始化一个ArrayList的默认容量大小为10,JDK1.8初始容量为空,等第一次添加数据时自动扩容,此时容量为10,再次扩容容量以1.5倍增大,这是面试过程中常被问到的一个问题,下边我们看一下源码:
JDK1.7
ArrayList底层object数组
private transient Object[] elementData; //存储ArrayList元素的数组缓冲区。
// 创建一个空构造ArrayList对象
ArrayList arr = new ArrayList();
/**
 * 底层创建了长度是10的Object[]
 */
无参构造函数
public ArrayList() {
    this(10);
}

this所调用函数
public ArrayList(int initialCapacity/*此时形参为10*/) {
    super();
    if (initialCapacity < 0)//不成立,抛出非法参数异常
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];//创建一个Object数组长度为10
}
JDK1.8
创建对象ArrayList arr = new ArrayList();//调用无参构造
调用无参构造函数
public ArrayList() {
	//private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
	//transient Object[] elementData;
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
	//将空Object[]数组对象赋值给elementData
}
第一次添加元素
public boolean add(E e) {
    ensureCapacityInternal(size + 1); // modCount增加
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
 	//当elementData == 空对象数组
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
         //DEFAULT_CAPACITY:默认容量 private static final int DEFAULT_CAPACITY = 10;
    	 //minCapacity:最小需要容量
    	 //取这两个中最大的一个作为最小需要容量
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}
扩容方法
/**
 * 增加容量,以确保它至少可以容纳由最小容量参数指定的元素数量。
 */
private void grow(int minCapacity) {
    /**
    1.oldCapacity:当前集合容量
    2.newCapacity:当前集合容量的1.5倍
    3.当newCapacity < 最小需要的容量值 将最小需要的容量值赋值给newCapacity
    4.当newCapacity > 最大数组长度 调用hugeCapacity方法;
      如果最小需要容量值 > 最大数组长度:返回 Integer.MAX_VALUE
    反之:返回最大容量值、将返回的值赋值给newCapacity
    5.调用Arrays.copyOf方法,赋值给一个指定的新长度的数组
    */
    1.int oldCapacity = elementData.length;
    2.int newCapacity = oldCapacity + (oldCapacity >> 1);
    3.if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    4.if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    5.elementData = Arrays.copyOf(elementData, newCapacity);
}

     2、LinkedList底层是一个双向链表,它比ArrayList更占用内存空间,因为每一个节点存储了两个引用单元,一个指向前一个元素,一个指向后一个元素,查询时间复杂度为O(n),但插入和删除较快其时间复杂度为O(1)。

    
 

路过

雷人

握手

1人点赞鲜花

鸡蛋

刚表态过的朋友 (1 人)

我有话说......

TA还没有介绍自己。

电话咨询: 135xxxxxxx
关注微信