集合快速入门及使用2

本文详细介绍了ArrayList和Vector在Java中的实现,包括ArrayList作为List接口的实现,泛型的使用,以及两者在底层扩容策略(无参和指定大小构造器)、线程安全性和效率上的对比。
摘要由CSDN通过智能技术生成

ArrayList

接上文,ArrayList实际上是List接口的实现类,底层实际上是数组,但该数组可以调整大小。

泛型

<E>是一种特殊的引用数据类型——泛型,泛型的用途很广,在本文就简单做一介绍,后续出专门的文章来解释泛型。泛型的“<>”中可以是任何数据类型,但其类型参数是在创建泛型类对象的时候就已经确定(例如ArrayList<Integer>),因为静态成员方法和变量是在类加载时就已经初始化,直接使用类名调用,因此在泛型的类型参数未确定时,静态成员有可能被调用,所以泛型的类型参数不能在静态成员中使用

ArrayList常用方法

//泛型定义为String类型
        ArrayList<String> arrayList = new ArrayList<>();
        //将指定的参数元素添加到集合
        arrayList.add("唐三");
        arrayList.add("小舞");
        arrayList.add("马红俊");
        //在指定的地方插入元素
        arrayList.add(1,"唐昊");

        //创建一个新集合
        ArrayList<String> arrayList1 = new ArrayList<>();

        arrayList1.add("朱竹清");
        arrayList1.add("奥斯卡");
        arrayList1.add("戴沐白");
        //将新集合所有元素添加到原集合
        arrayList.addAll(arrayList1);
        
        //获取集合元素个数
        arrayList.size();

        //获取指定索引的元素
        arrayList.get(1);

ArrayList底层扩容实现原理:

private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // preconditions not checked because of inlining
        // assert oldLength >= 0
        // assert minGrowth > 0

        int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
        if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
            return prefLength;
        } else {
            // put code cold in a separate method
            return hugeLength(oldLength, minGrowth);
        }
    }

底层扩容关键源码如上,其中可以发现当创建ArrayList对象时,如果使用的是无参构造器,初始的容量为0,第一次添加容量为10,如需要再此添加,则按1.5倍数扩充;如果使用的是指定大小的构造器,则初始的容量为指定大小,如果需要扩容,则直接按1.5倍扩容。

Vector

Vector底层是一个对象数组,protected Object[] elementData;

Vector是线程同步的,线程安全,在开发中,需要线程同步安全时,往往采用Vector

//无参构造器
public Vector() {
        this(10);
}
public synchronized boolean add(E e) {
        modCount++;
        add(e, elementData, elementCount);
        return true;
}
public synchronized void ensureCapacity(int minCapacity) {
        if (minCapacity > 0) {
            modCount++;
            if (minCapacity > elementData.length)
                grow(minCapacity);
        }
}
private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = ArraysSupport.newLength(oldCapacity,
                minCapacity - oldCapacity, /* minimum growth */
                capacityIncrement > 0 ? capacityIncrement : oldCapacity
                                           /* preferred growth */);
        return elementData = Arrays.copyOf(elementData, newCapacity);
}

Vector底层源码解读可知,如果是无参,默认为10,满后,按2倍扩容,指定大小后每次直接按照2倍扩容。

Vector与ArrayList比较

底层结构版本

线程安全与效率

扩容倍数
ArrayList可变数组

jdk1.2

不安全,效率高

有参:1.5倍数

无参:第一次10,

第二次按1.5倍扩充

Vector可变数组Object[]

jdk1.0

安全,效率不高

无参,默认10,满后按两倍扩容

指定大小,每次直接2倍数扩充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值