Java——ArrayList(动态数组)介绍

一、简介


ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
在这里插入图片描述
ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>();  // 初始化
  • E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
  • objectName: 对象名。

注:

  1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  2. ArrayList实现了Cloneable接口,表明ArrayList可以clone的
  3. ArrayList实现了Serializable接口,表明ArrayList支持序列化的
  4. Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
  5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表。

二、使用


1、构造

ArrayList有三种构造方式:无参构造、利用其他的collection构造、指定顺序表的初始容量。

1.1 无参构造

无参构造类型是推荐的写法。

//Integer为整型的包装类型
List<Integer> list = new ArrayList<>();

1.2 指定初始容量

 List<Integer> list = new ArrayList<>(10);
 list.add(1);
 list.add(2);
 list.add(3);

1.3 利用其他的collection进行构造

//构建一个与list1元素一样的list
 ArrayList<Integer> list2 = new ArrayList<>(list1);

注: 无论哪种构造形式,都应该避免省略类型,任意类型的元素都能够存放,使用时会带来很多麻烦。

2、基础操作

2.1 添加元素

添加元素到 ArrayList 可以使用 add() 方法:

public class Test{
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<String>();
        sites.add("Hello");
        sites.add("CSDN");
        System.out.println(array);
    }
}

在这里插入图片描述

2.2 删除元素

删除元素使用remove()方法:

public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("IDEA");
        array.add("Java");
        System.out.println(array);
        array.remove(2);
        System.out.println(array);
    }
}

在这里插入图片描述

2.3 修改元素

修改元素可以使用 set() 方法:

public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("IDEA");
        array.add("Java");
        System.out.println(array);
        array.set(2,"python"); // 第一个参数为索引,第二个参数为要修改的值
        System.out.println(array);
    }
}

在这里插入图片描述

2.4 访问元素

访问元素使用get()方法:

public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("IDEA");
        array.add("Java");
        System.out.println(array);
        System.out.println(array.get(2)); // 获取位置2的元素

    }
}

在这里插入图片描述

2.5 计算大小

计算数组内元素个数使用size()方法:

public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("IDEA");
        array.add("Java");
        System.out.println(array);
        System.out.println(array.size());
    }
}

在这里插入图片描述

2.6 遍历数组

遍历数组有三种方式:for循环遍历、for-each遍历、迭代器遍历。

public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("IDEA");
        array.add("Java");
        System.out.println(array);
        
        System.out.println("for:");
        for (int i = 0; i < array.size(); i++) {
            System.out.print(array.get(i)+" ");
        }
        System.out.println();

        System.out.println("for-each:");
        for (String j:array) {
            System.out.print(j+" ");
        }
        System.out.println();

        System.out.println("迭代器:");
        Iterator<String> it = array.listIterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
        System.out.println();
    }

在这里插入图片描述

3、常用操作

方法作用
void add(int index, E element)将element元素插入到index位置
boolean addAll(Collection<? extends E> c)将c中的元素全部插入
boolean remove(Object o)删除第一个遇到的o元素
void clear()清空
boolean contains(Object o)判断o是否在表中
int indexOf(Object o)返回第一个o所在的下标
int lastIndexOf(Object o)返回最后一个o的下标
List<E> subList(int fromIndex, int toIndex)截取fromindex到toindex的元素
public class Test {
    public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<>();
        ArrayList<String> array2 = new ArrayList<>();
        array.add("Hello");
        array.add("CSDN");
        array.add("Java");
        array.add("IDEA");

        array2.add("python");
        array2.add("Java");

        array.add(1,"Data");
        System.out.println("array = " + array);
        
        array2.addAll(array);
        System.out.println("array2 = " + array2);

        array2.remove("Data");
        System.out.println("array2 = " + array2);

        array.clear();
        System.out.println("array = " + array);

        System.out.println("Java是否在表中:" + array2.contains("Java"));

        System.out.println("array2.indexOf(\"Java\") = " + array2.indexOf("Java"));

        System.out.println("array2.lastIndexOf(\"Java\") = " + array2.lastIndexOf("Java"));

        System.out.println("array2.subList(1,4) = " + array2.subList(1,4));
    }

在这里插入图片描述

4、扩容机制

ArrayList是一个动态类型的顺序表,即,在插入元素的过程中会自动扩容:

    Object[] elementData; // 存放元素的空间
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间
    private static final int DEFAULT_CAPACITY = 10; // 默认容量大小
    public void ensureCapacity(int minCapacity) {
        // 计算最小的扩容大小
        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)? 0 :
                DEFAULT_CAPACITY;

        // 检测是否需要扩容
        if (minCapacity > minExpand) {
            ensureExplicitCapacity(minCapacity);
        }
    }
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // 如果minCapacity比数组的容量大,就调用grow进行扩容
        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;

        // 如果需要扩容大小超过MAX_ARRAY_SIZE,重新计算容量大小
        if (newCapacity - MAX_ARRAY_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();

        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; 
    }

三、模拟实现ArrayList


为了更好的理解和使用ArrayList,对其进行了模拟实现
之前单独写过一篇博客进行模拟:Java——模拟实现ArrayList(动态数组)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值