Array List与顺序表

学习目标

  1. 线性表
  2. 顺序表与链表的简单了解
  3. ArrayList的介绍
  4. ArrayList的扩容机制

 

  1. 线性表

线性表(linear list): 是由n且具有相同的特性数据元素的有限列表, 线性表在实际运用中常见的数据结构, 常见的线性表: 栈 , 堆 , 队列 , 顺序表 , 链表…

链表:在逻辑上是连续的数据结构, 但在物理结构上不一定是连续的, 用顺序表和链表实现线性表时可以明显观察出区别.

2,顺序表

顺序表是在物理上是用一段连续的物理内存保存数据元素的线性结构, 一般情况下使用数组储存. 在数组上完成增删改查.

链表是在逻辑上保存数据元素的线性结构, 每个数据元素可能分布在内存的各个地方 ,主要通过next找到下个元素数据.

3 ArrayList简介

在集合框架中 ArrayList是一个普通类, 实现了List接口

【说明】

1. ArrayList是以泛型方式实现的,使用时必须要先实例化

2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问

3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的

4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的

5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可

选择Vector或者

6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表\

  3.1 ArrayList的构造方法

3.2ArrayList 的常见操作

ArrayList提供的方法有诸多,但我们只需掌握常见方法即可

4 . ArrayLists的扩容机制

       此处的下面代码能否执行?为什么?

ArrayList是一个动态类型的顺序表, 在插入数据时会检查数组大小, 当数组满时会进行自动扩容

ArrayList的部分源码

Object[] elementData;   // 存放元素的空间

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};  // 默认空间

private static final int DEFAULT_CAPACITY = 10;  // 默认容量大小

 

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!

    elementData[size++] = e;
    return true;
}
 

private void ensureCapacityInternal(int minCapacity) {
 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
 

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
   }
    return minCapacity;
}
 

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
 
    // overflow-conscious code

    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
 

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private void grow(int minCapacity) {
    // 获取旧空间大小

    int oldCapacity = elementData.length;
    
    // 预计按照1.5倍方式扩容

    int newCapacity = oldCapacity + (oldCapacity >> 1);
    
    // 如果用户需要扩容大小 超过 原空间1.5倍,按照用户所需大小扩容

    if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity;
    if(newCapacity - MAX_AEEAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
//调用copyOf扩容
    elementData = Arrays.copyOf(elementData , newCapacity);
    }
private static int hugeCapacity(int minCapacity){
// 如果minCapacity小于0 ,抛出OutOfMemoryError异常
    if(minCapacity < 0)
        throw new OutOfMemoryError();
    retur (minCapacity > MAX_AEEAY_SIZE)? lnterger.MAX_VALUE:MAX_ARRAY_SIZE;
}
}

总 结 :

1. 检 测 是 否 真 正 需 要 扩 容 , 如 果 是 调 用 g r o w 准 备 扩 容

2. 预 估 需 要 库 容 的 大 小 初 步 预 估 按 照 1.5 倍 大 小 扩 容 如 果 用 户 所 需扩容的 大 小 超 过 预 估 1.5 倍 大 小 , 则 按 照 用 户 所 需 大 小 扩 容 , 真 正 扩 容 之 前 检 测 是 否 能 扩 容 成 功 , 防 止 太 大 导 致 扩 容 失 败

3. 使 用 c o p y O f进 行 扩 容

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值