java集合-ArrayList和Vector类

前言

List集合代表一个元素 有序、可重复的 集合, 集合中每个元素都有其对应的顺序索引。

  • 有序性
  • 可重复性

List默认的话是按照元素的添加顺序设置元素的索引。

下面简单了解一下List的一些用的比较多的方法:

List作为 Collection接口的子接口 ,可以使用Collection接口里的全部方法,除此之外根据它的 有序性,List集合里还新增了一些根据索引来操作集合元素的方法。

  • void add(int index, Object o): 将元素o插入到 List 集合的 index 处。
  • boolean addAll(int index, Collection c): 将集合c的所有元素都插入到集合的 index 处。
  • Object get(int inedx): 返回集合的 index 索引处的元素。
  • int indexOf(Object o): 找到元素o在集合中第一次出现的位置所对应的索引。
  • int lastIndexOf(Object o): 找到元素o在集合中最后一次出现的位置所对应的索引。
  • void sort(Comparator c): 根据 Comparator 参数对 List 集合的元素排序。(Java 8)

相信大部分人都有用过这些方法,那么接下来我们看看 List 的两个比较经典的实现类, ArrayListVector

那现在我们知道 ArrayList 和 Vector 都是作为 List 的实现类,完全是支持 List 接口的全部功能的,那么这两个实现类到底有什么区别?

ArrayList和Vector实现类

现在再讲一次哈,看看大家有没有看出什么区别:

ArrayList 和 Vector 类都是 基于数组 实现的List类。

牛,我不小心把重点画出来了,对没错,基于数组这个很重要,我们都知道,数组是 没有办法改变长度 的, 但是 ArrayList 和 Vector 类里面 都封装了一个动态的、允许再分配的 Object[] 数组 。(这里的话一般没了解过的就到头了呀,我平时就 add 就好了,也没有仔细了解过它到底规定的数组长度是怎么设定的。你van了你知道不!)。

这里我们回顾一下数组的定义:

int nums = new int[10]; // 很明显这就是定长吧!

但ArrayList和Vector对象会使用一个参数: initialCapacity 参数来设置数组的长度,当向 ArrayList 和 Vector 中添加元素超出了该参数大小时,它们的 initialCapacity 会自动增加。这里的话我们会经常被问到:

如果向 ArrayList 和 Vector 中添加大量的元素时,会有什么情况发生?如何避免这种情况?

这里的话我们简单看一下 ArrayList扩容 的最终代码是怎么实现的:

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 新容量一般为旧容量的两倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 比较 新增元素的容量 与 扩容完的旧容量 的大小
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        // 复制生成到一个新的集合中,新集合的容量为 newCapacity
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

不慌,不复杂,还挺简单的,我们前面都可以先不看了,看到最后一句了没有:

elementData = Arrays.copyOf(elementData, newCapacity);

这里我们可以理解为: 每一次扩容都有一定的资源的消耗。

所以会有什么情况发生? 答: 大量的元素添加会使得集合的大小经常超出限制,导致集合一直 反复的扩容 ,而每一次的扩容都是会 消耗性能 的,所以我们可以从减少集合扩容的角度去解决这个问题。

如何避免这种情况? 答: 可以使用 ensureCapacity(int minCapacity) 方法一次性增加 initialCapacity,这可以 减少重分配次数 ,从而提高性能。

当然,如果一开始就知道 ArrayList 或 Vector 需要保存多少个元素,则可在创建时就指定他们的 initialCapacity 大小。如果创建空的 ArrayList 或 Vector 集合时不指定 initialCapacity 参数,则Object[]数组的长度默认为10。

ArrayList和Vector通常都用下面这两种方法来重新分配 Object[] 数组:

  • void ensureCapacity(int minCapacity): 将 ArrayList 或 Vector 集合的 Object[] 数组长度增加到大于或等于 minCapacity 的值。
  • void trimToSize(): 调整 ArrayList 或 Vector 的数组长度的值为当前元素的个数,这么调整的好处在于可以 减少集合对象所占用的内存空间

ArrayList和Vectorr究竟有啥区别

先看看Vector的历史 ,从上面我们可以看出,ArrayList 和 Vector 在用法上几乎完全相同,但由于 Vector 是一个古老的集合( JDK1.0就有了 ),那时候 Java 还没有提供系统的集合框架,所以 Vector 里提供了一些类似于 addElement(Object obj) 的方法, 这实际上又和 add(Object obj) 没有任何的区别。

从Java1.2以后, Java 提供了系统的集合框架,才将 Vector 改为实现 List 接口,作为List的实现之一存在,从而导致了 Vector 里面有一些功能重复的方法。其中的话,方法名比较长的方法都是 Vector 原有的方法,如图我们看看Vector类里面的结构:

vector-structure

可以看到里面有两套操作集合元素的实现等等( 这里框了Vector原本实现的那套 ),Java改写这些方法,将其缩短,实际上就是为了简化编程。

ArrayList 和 Vector 的特别不一样的地方是:

  • ArrayList是线程不安全的 ,当多个线程访问同一个 ArrayList 集合时,如果超过一个线程修改了 ArrayList 集合,则程序必须手动保证集合的同步性。
  • Vector是线程安全的 ,Vecto r类无需程序保证集合的同步性。但因为如此, Vector 的效率会比 ArrayList 要低。( 看源码可以看到方法都带了 synchronized 关键字 )

但即使如此,也同样不推荐使用 Vector 实现类,因为有一个工具类 Collections , 它可以将 ArrayList 变成线程安全的,如图这几个方法可以做到,有兴趣的话可以自己先了解一下咯:

Collections-synchronized

除此之外,Vector 还提供了一个 Stack 子类,它用于模拟 "栈" 这种数据结构, "栈" 通常指的是 后进先出(LIFO) 的容器。最后 push 的元素, 最先被 pop 出栈。与Java的其它集合一样,进栈出栈的都是Object。下面看看几个Stack类提供的方法:

  • Object peek(): 返回 "栈" 的第一个元素, 但并不 pop 出栈。
  • Object pop(): 返回 "栈" 第一个元素, 并且 pop 出栈。
  • void push(Object obj): 将一个元素 push 进栈, 最后一个 push 进栈的元素一般位于 栈顶 位置。

由于 Stack 继承了 Vector, 所以 Stack 也是个 比较古老 的类了, 它也是 线程安全性能比较差 的类了(尽量少用吧)。所以真的要使用 "栈" 的话,可以考虑一下用 ArrayDeque 类哦, 有机会我也会详细介绍一下的!

都结合网上资料加上自己的一些理解,如果有影响到他人的地方,可以联系我删除:[email protected]

你可能感兴趣的:(java集合-ArrayList和Vector类)