List集合简介

一.List集合的特点

 1.list集合容器具备增删改查
 2.有序
 3.元素可重复

二,List主要包含的内容

List集合中的元素都对应一个整数型的序号记载其在集合中的位置,可以根据序号存取集合中的元素。

JDK API所提供的List集合类常用的有:

ArrayList

​ LinkedList

Vector

三,ArrayList

ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。 第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组。

其底层代码为

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private transient Object[] elementData;
private int size;

public ArrayList() {
    this.elementData = EMPTY_ELEMENTDATA;
}

public boolean add(Object e) {
    ensureCapacityInternal(size + 1);
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

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

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    elementData = Arrays.copyOf(elementData, newCapacity);
}

elementData数组用于存储元素,size表示当前ArrayList中的元素个数。ensureCapacityInternal方法用于确保数组容量足够,如果不够则进行扩容。grow方法实现了数组的扩容逻辑,当需要扩容时,会创建一个新的数组,并将原数组中的元素复制到新数组中。

需要注意的是,由于elementData是Object类型的数组,因此在添加元素时需要进行类型转换。ArrayList的底层实现主要依赖于数组的动态扩容和复制操作来实现动态数组的功能。

四,LinkedList

它是一个双向链表实现的列表。LinkedList中的每个元素都包含了对前一个元素和后一个元素的引用,因此可以实现快速的插入和删除操作。相比于ArrayList,LinkedList在插入和删除操作上有更好的性能表现,但在随机访问时性能较差。

private static class Node<E> {
    E item;
    Node<E> prev;
    Node<E> next;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.prev = prev;
        this.next = next;
    }
}

private transient Node<E> first;
private transient Node<E> last;
private transient int size;

public LinkedList() {
    this.size = 0;
}

public boolean add(E e) {
    linkLast(e);
    return true;
}

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null) {
        first = newNode;
    } else {
        l.next = newNode;
    }
    size++;
}

LinkedList使用Node类来表示链表中的每个节点,每个节点包含了元素本身以及对前一个节点和后一个节点的引用。LinkedList中的firstlast分别表示链表的头结点和尾节点,size表示链表中元素的个数。

linkLast方法用于在链表尾部添加一个新节点,它会创建一个新的节点,并将其插入到链表的尾部。在LinkedList中,插入和删除操作都是通过修改节点之间的引用来实现的,因此在插入和删除操作上有较好的性能表现。

需要注意的是,LinkedList并不是线程安全的,如果需要在多线程环境下使用,可以考虑使用Collections.synchronizedList方法来创建一个线程安全的LinkedList。LinkedList适用于需要频繁进行插入和删除操作的场景。

五,Vector

Vector可以根据需要自动增长和缩小,类似于ArrayList,但与ArrayList不同的是,Vector是同步的,即它的所有方法都是同步的,可以在多线程环境下安全地使用。

以下是Vector的一些特点和用法:

  1. Vector中的元素可以是任意对象,包括null
  2. Vector可以通过add()方法添加元素,通过get()方法获取元素,通过remove()方法删除元素等。
  3. Vector还提供了一些其他方法,如contains()indexOf()size()等,用于操作和查询元素。
  4. 由于Vector是同步的,因此在多线程环境下使用时,可以确保线程安全,但也会带来一定的性能开销。

虽然Vector在多线程环境下提供了线程安全的操作,但在单线程环境下,推荐使用ArrayList,因为ArrayList不带来额外的同步开销。

六,ArrayList与LinkedList的区别

  1. 内部实现结构不同:ArrayList基于数组实现,而LinkedList基于双向链表实现。

  2. 随机访问性能不同.

  3. 插入和删除性能不同:在ArrayList中,插入和删除操作可能需要移动后续元素,而LinkedList在插入和删除时只需调整指针

  4. 内存占用不同:由于ArrayList需要预分配一定大小的数组空间,可能会存在一定的内存浪费;而LinkedList的内存占用相对更灵活,只需存储节点和指针。

如果需要频繁进行随机访问操作,且对内存占用要求较高,可以选择ArrayList;如果需要频繁进行插入和删除操作,且对内存占用要求较低,可以选择LinkedList。

七.Vector与ArrayList的区别

  1. 线程安全性不同:Vector是线程安全的,而ArrayList不是。在多线程环境下,使用Vector可以避免并发访问导致的问题。

  2. 扩容机制不同:Vector在扩容时会增加一倍的大小,而ArrayList默认情况下增加50%的大小。这意味着在大部分情况下,ArrayList的扩容开销会更小。

  3. 性能差异:由于Vector是线程安全的,会涉及到额外的同步开销,因此在单线程环境下,ArrayList的性能可能会更好一些。

  4. 遗留问题:Vector是Java早期版本提供的类,而ArrayList是Java集合框架的一部分。因此,ArrayList在设计和性能上可能更加优化。

一般情况下推荐使用ArrayList而不是Vector,除非在需要线程安全性的情况下才考虑使用Vector。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值