博客
关于我
List集合(源码学习)
阅读量:643 次
发布时间:2019-03-14

本文共 5413 字,大约阅读时间需要 18 分钟。

List集合详解:ArrayList、LinkedList、Vector与Stack

摘要

List集合是属于集合接口的一种特殊集合,其主要特点是支持有序、可重复以及通过索引进行快速元素操作。Java提供了三种主要的List实现类:ArrayList、LinkedList和Vector,除此之外,Stack作为Vector的子类也提供了一个典型的栈实现。本文将从ArrayList的详细实现原理入手,接着比较不同List实现类的优缺点,最后深入探讨Vector及Stack的应用场景及其实现细节。

List集合概述

List集合是集合接口中的一种特殊集合,其特点包括:

  • 有序:集合中的元素按照一定规则排列,支持通过索引快速访问。
  • 可重复:同一个元素可以多次存在于集合中。
  • 可null元素:List集合允许包含Null元素,这与集合的其他实现(如Set)不同。

List集合的核心特征体现在其支持默认的implemented methods,包括:

  • add方法:支持插入元素
  • remove方法:支持删除元素
  • contains方法:支持元素存在性查询
  • get方法:支持按索引查询元素
  • containsAll方法:支持查询多个元素的存在性
  • size方法:支持返回集合大小
  • isEmpty方法:支持判断集合是否为空
  • iterator方法:支持创建迭代器进行集合遍历

List集合类型比较:ArrayList详解

ArrayList基本特性

ArrayList是基于数组的动态容器,其实现基于一个动态大小的数组,因此其在随机访问(get方法)和元素遍历(iterator)方面操作极其高效。但在单个元素插入和删除操作时,由于需要进行数组的动态扩展或收缩,操作效率较低。

ArrayList初始化方式

ArrayList提供了三种主要的初始化方式:

  • 默认初始化:初始化时使用默认容量10,适合大多数场景。
  • public ArrayList() {    elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
    1. 指定容量:允许开发者根据需求初始化指定容量。
    2. public ArrayList(int initialCapacity) {    if (initialCapacity > 0) {        elementData = new Object[initialCapacity];    } else if (initialCapacity == 0) {        elementData = EMPTY_ELEMENT_DATA;    } else {        throw new IllegalArgumentException("Illegal capacity: " + initialCapacity);    }}
      1. 从Collection复制:支持接收其他集合的元素进行初始化。
      2. public ArrayList(Collection c) {    elementData = c.toArray();    if ((size = elementData.length) != 0) {        if (elementData.getClass() != Object[].class)            elementData = Arrays.copyOf(elementData, size, Object[].class);    } else {        elementData = EMPTY_ELEMENT_DATA;    }}

        ArrayList的扩容机制

        ArrayList的动态扩容机制是维护一个扩容阈值的策略,以确保在元素添加时不会因为容量不足而导致内存溢出。具体来说:

      3. 默认扩容策略:当元素数量超过当前数组容量的1.5倍时会扩容。
      4. 双倍扩容:当新容量不足以满足当前插入需求时,将根据需求动态调整新容量。
      5. 特殊容量处理:如果容量超过了默认的Integer.MAX_VALUE - 8,则视为最大可能值。
      6. 异桩扩容:通过堆积式扩容以提升效率。
      7. 示例分析

        • 第一个元素加入时,数组大小为0,将通过扩容机制扩充至10。
        • 当需要添加第十一(11)个元素时,当前数组大小为10,满足容量的1.5倍(10*1.5=15),所以当需要加入第十一(11)个元素时,会扩容至20。

        ArrayList的基本操作

        ArrayList的核心操作方法包括:

        • add方法:负责元素的插入,默认实现通过数组的append操作。
        • remove方法:负责元素的删除,当删除元素时需要处理数组的连续性调整。
        • get方法:通过数组下标直接获取元素,实现随机访问。
        • ** iterator 方法**:提供一个迭代器,负责按顺序遍历集合中的所有元素。

        代码示例

        public class TestArrayList {    public static void main(String[] args) {        ArrayList
        list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); System.out.println("元素数量:" + list.size()); for (String s : list) { System.out.println("元素:" + s); } }}

        LinkedList详解:基于链表的双向列表

        LinkedList特性

        LinkedList 的特点包括:

        • 双向链表结构:每个节点包含前驱和后继指针。
        • 增删快、查询慢:插入和删除操作平均时间复杂度为O(1),查询操作的平均复杂度为O(n)。
        • 绝对的线性数组表现:当List的元素数量较大时,List实现类的性能差异会变得更加明显。
        • 高内维度操作:在单线程环境下,LinkedList的性能优于ArrayList,但在多线程环境下,ArrayList的性能优势更为突出。

        代码示例

        public class TestLinkedList {    public static void main(String[] args) {        LinkedList
        list = new LinkedList<>(); list.add("a"); list.add("b"); list.add("c"); System.out.println("元素数量:" + list.size()); for(String s : list) { System.out.println("元素:" + s); } }}

        Vector的线程安全实现

        Vector集合的特点包括:

        • 线程安全:通过对所有公用操作的同步保护,确保多线程环境下的数据一致性。
        • 同步机制:核心方法(如add、remove、contains等)都带有 synchronized 关键字。
        • 同步策略:所有修改集合元件的操作都需要获得集合的内部锁,这保证了在多线程环境下集合的安全使用。

        并发测试示例

        import java.util.Vector;import java.util.concurrent.CountDownLatch;public class ConcurrentVectorTest {    public static void main(String[] args) throws InterruptedException {        CountDownLatch countDownLatch = new CountDownLatch(2);        Vector
        vector = new Vector<>(); MyThread myThread1 = new MyThread(countDownLatch, vector, "abc"); MyThread myThread2 = new MyThread(countDownLatch, vector, "abc"); myThread1.start(); myThread2.start(); countDownLatch.await(); System.out.println("集合大小:" + vector.size()); for(int i = 0; i < vector.size(); i++) { System.out.println("索引:" + i + " 元素:" + vector.get(i)); } } static class MyThread extends Thread { private CountDownLatch countDownLatch; private Vector
        vector; private String element; public MyThread(CountDownLatch countDownLatch, Vector
        vector, String element) { this.countDownLatch = countDownLatch; this.vector = vector; this.element = element; } @Override public void run() { try { if (!vector.contains(element)) { Thread.sleep(1000); vector.add(element); } } catch (InterruptedException e) { e.printStackTrace(); } finally { countDownLatch.countDown(); } } }}

        Stack的实现与应用

        Stack类是Vector的一个内部扩展类,提供一个典型的先进后出的栈操作。Stack的主要操作包括:

        • push:将元素压入栈顶。
        • pop:将栈顶元素弹出。
        • peek:查看栈顶元素。
        • search:查找栈中的元素。

        Stack的实现主要依赖于内部维护的一个动态数组:

        public class Stack
        extends Vector
        { public Stack() { super(); } public boolean push(E item) { return super.addElement(item); } @Override public E pop() { return super.removeElementAt(size()); } @Override public E peek() { return super.elementAt(size()); }}

        总结

        List集合在Java中扮演着关键的数据结构角色,其主要应用场景包括:

        • 数据存储与管理:用于有序存储大量数据。
        • 广度优先搜索(BFS):在图结构中,List集合可以用作队列,实现广度优先搜索。
        • 中间结果缓存:用于临时存储中间处理的数据。

        选择List集合的具体实现类取决于具体需求:

        • ArrayList:适合对随机访问和数据迭代要求较高的场景。
        • LinkedList:适合对插入、删除操作要求低,且不介意查询效率较高的场景。
        • Vector:适合线程安全要求严格,且需要随机访问的场景。
        • Stack:适合模拟栈结构,典型场景包括括号匹配、调用栈等。

        通过合理选择List集合的实现类,可以在不同的场景下实现最优的性能表现。

    转载地址:http://nqqoz.baihongyu.com/

    你可能感兴趣的文章
    NodeJS、NPM安装配置步骤(windows版本)
    查看>>
    NodeJS、NPM安装配置步骤(windows版本)
    查看>>
    nodejs与javascript中的aes加密
    查看>>
    nodejs中Express 路由统一设置缓存的小技巧
    查看>>
    Nodejs中的fs模块的使用
    查看>>
    nodejs包管理工具对比:npm、Yarn、cnpm、npx
    查看>>
    NodeJs单元测试之 API性能测试
    查看>>
    nodejs图片转换字节保存
    查看>>
    nodejs字符与字节之间的转换
    查看>>
    NodeJs学习笔记001--npm换源
    查看>>
    NodeJs学习笔记002--npm常用命令详解
    查看>>
    nodejs学习笔记一——nodejs安装
    查看>>
    nodejs封装http请求
    查看>>
    nodejs常用组件
    查看>>
    nodejs开发公众号报错 40164,白名单配置找不到,竟然是这个原因
    查看>>
    Nodejs异步回调的处理方法总结
    查看>>
    NodeJS报错 Fatal error: ENOSPC: System limit for number of file watchers reached, watch ‘...path...‘
    查看>>
    Nodejs教程09:实现一个带接口请求的简单服务器
    查看>>
    nodejs服务端实现post请求
    查看>>
    nodejs框架,原理,组件,核心,跟npm和vue的关系
    查看>>