Java集合框架之List

1.List集合概要

Java集合框架之List

2.Iterable接口

1.概要

Java集合框架之List
2.重要方法
  1. forEach方法:对Collection集合中的每个对象进行消费
List<student> list = Stream.generate(() -> new Student("&#x5F20;&#x4E09;", 23)).limit(100).collect(Collectors.toList());
list.forEach(System.out::println);
</student>
  1. spliterator方法:获取Spliterator迭代器

3.Collection接口

1.重要方法
  1. spliterator():创建Spliterator
  2. stream():创建串行流Stream
  3. parallelStream():创建并行流Stream

4.RandomAccess接口

1.概要

这是一种标识型接口,用于标识某个类具有某种功能特性的接口。

Java集合框架之List

5.Vector

1.Vector集合概要

Vector是一个线程安全的集合,其中的大部分方法都加了synchronized关键字。

Java集合框架之List
2.重要变量
  1. Vector中重要的变量信息
// &#x96C6;&#x5408;Vector&#x5B58;&#x653E;&#x5BF9;&#x8C61;&#x7684;&#x6570;&#x7EC4;
protected Object[] elementData;
// &#x96C6;&#x5408;Vector&#x5B58;&#x50A8;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;
protected int elementCount;
// elementData&#x6570;&#x7EC4;&#x6BCF;&#x6B21;&#x6269;&#x5BB9;&#x7684;&#x5927;&#x5C0F;
protected int capacityIncrement;
3.Vector的扩容操作
  1. 初始化Vector的扩容操作
// 1. &#x6307;&#x5B9A;&#x4E86;&#x521D;&#x59CB;&#x5316;&#x5BB9;&#x91CF;&#x548C;&#x6BCF;&#x6B21;&#x6269;&#x5BB9;&#x65F6;&#x7684;&#x589E;&#x91CF;
// &#x5219;&#x4E0B;&#x6B21;&#x6269;&#x5BB9;&#x4E3A;initialCapacity + capacity&#xFF0C;&#x4F9D;&#x6B21;&#x7C7B;&#x63A8;
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}

// 2. &#x6307;&#x5B9A;&#x521D;&#x59CB;&#x5316;&#x5BB9;&#x91CF;&#x548C;&#x6BCF;&#x6B21;&#x6269;&#x5BB9;&#x65F6;&#x7684;&#x589E;&#x91CF;&#x4E3A;0
// &#x5219;&#x4E0B;&#x6B21;&#x6269;&#x5BB9;&#x4E3A;2 * initialCapacity
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}

// 3.&#x6307;&#x5B9A;&#x521D;&#x59CB;&#x5316;&#x5BB9;&#x91CF;&#x4E3A;10&#xFF0C;&#x5219;&#x4E0B;&#x6B21;&#x6269;&#x5BB9;&#x4E3A;20&#xFF0C; 40...

public Vector() {
    this(10);
}
  1. 向集合Vector添加对象,elementData数组容量不足时:2倍扩容
// minCapacity&#x4E3A;&#x671F;&#x671B;&#x7684;elementData&#x6570;&#x7EC4;&#x5BB9;&#x91CF;
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    // &#x5BA2;&#x6237;&#x6307;&#x5B9A;&#x7684;&#x6BCF;&#x6B21;&#x6570;&#x7EC4;&#x6269;&#x5BB9;&#x5927;&#x5C0F;&#x8D85;&#x8FC7;0&#xFF0C;&#x5219;&#x6269;&#x5BB9;&#x4E3A;newCapacity = oldCapacity + capacityIncrement
    // &#x5426;&#x5219;&#x8FDB;&#x884C;2&#x500D;&#x6269;&#x5BB9;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    // &#x786E;&#x4FDD;&#x6570;&#x7EC4;&#x6269;&#x5BB9;&#x4E3A;&#x671F;&#x671B;&#x7684;elementData&#x6570;&#x7EC4;&#x5BB9;&#x91CF;
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}
  1. 客户端重新设置Vector的容量时,可能会进行扩容操作
public synchronized void setSize(int newSize) {
    modCount++;
    // &#x65B0;&#x5BB9;&#x91CF;&#x5927;&#x4E8E;&#x5F53;&#x524D;Vector&#x96C6;&#x5408;&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;&#x5219;&#x8FDB;&#x884C;&#x6269;&#x5BB9;
    if (newSize > elementCount) {
        ensureCapacityHelper(newSize);
    } else {
        for (int i = newSize ; i < elementCount ; i++) {
            elementData[i] = null;
        }
    }
    elementCount = newSize;
}

6.ArrayList

1.ArrayList概要

ArrayList是一个多线程环境下有些操作不安全的集合

Java集合框架之List
2.ArrayList集合中重要的常量和变量
// &#x9ED8;&#x8BA4;&#x7684;&#x521D;&#x59CB;&#x5316;&#x6570;&#x7EC4;&#x5BB9;&#x91CF;
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// &#x5B58;&#x653E;&#x96C6;&#x5408;ArrayList&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x7684;&#x6570;&#x7EC4;
transient Object[] elementData;
// &#x96C6;&#x5408;ArrayList&#x4E2D;&#x5305;&#x542B;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;
private int size;
3.ArrayList集合的初始化操作
// &#x4F7F;&#x7528;&#x6307;&#x5B9A;&#x7684;&#x521D;&#x59CB;&#x5316;&#x5BB9;&#x91CF;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

// &#x6784;&#x9020;&#x4E00;&#x4E2A;&#x957F;&#x5EA6;&#x4E3A;0&#x7684;ArrayList&#x96C6;&#x5408;&#xFF0C;
// &#x540E;&#x9762;&#x4F7F;&#x7528;add&#x65B9;&#x6CD5;&#x6DFB;&#x52A0;&#x5143;&#x7D20;&#x4F1A;&#x5C06;elementData&#x6269;&#x5BB9;&#x6210;&#x957F;&#x5EA6;&#x4E3A;10&#x7684;&#x6570;&#x7EC4;
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

// &#x6839;&#x636E;&#x53E6;&#x4E00;&#x4E2A;&#x96C6;&#x5408;&#x6784;&#x9020;ArrayList
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.

        this.elementData = EMPTY_ELEMENTDATA;
    }
}
4.ArrayList的扩容操作
  1. 扩容:按照1.5倍扩容
// minCapacity&#x4E3A;&#x671F;&#x671B;&#x7684;&#x6570;&#x7EC4;&#x6700;&#x4F4E;&#x5BB9;&#x91CF;&#xFF08;&#x5373;&#x539F;&#x6570;&#x7EC4;&#x5BB9;&#x91CF; + 1&#xFF09;
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    // 1.5&#x500D;&#x8FDB;&#x884C;&#x6269;&#x5BB9;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // &#x786E;&#x4FDD;&#x5BB9;&#x5668;&#x8FBE;&#x5230;&#x6700;&#x4F4E;&#x5BB9;&#x91CF;10&#xFF0C;&#x6700;&#x4F4E;&#x4E0B;&#x9650;
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    // &#x786E;&#x4FDD;&#x5BB9;&#x5668;&#x7684;&#x6700;&#x5927;&#x5BB9;&#x91CF;&#xFF0C;&#x6700;&#x5927;&#x4E0A;&#x9650;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}
5.ArrayList内部数组的移动操作
  1. 移动数组元素的操作都是通过 System.arraycopy这个本地方法完成。
6.ArrayList的删除操作removeIf
  1. 删除操作removeIf方法中使用BitSet根据相应的位标记需要删除的元素。
// size&#x4E3A;&#x5BB9;&#x5668;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x4E2A;&#x6570;
final BitSet removeSet = new BitSet(size);
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
    @SuppressWarnings("unchecked")
    final E element = (E) elementData[i];
    if (filter.test(element)) {
        // &#x9700;&#x8981;&#x5220;&#x9664;&#x7684;&#x5143;&#x7D20;&#x6807;&#x8BB0;&#x4E3A;1
        removeSet.set(i);
        // &#x7EDF;&#x8BA1;&#x9700;&#x8981;&#x5220;&#x9664;&#x7684;&#x5143;&#x7D20;&#x4E2A;&#x6570;
        removeCount++;
    }
}

7.Vector和ArrayList的对比
  1. 两者的内部结构都是数组。
  2. Vector集合默认采用当前容量的1倍大小进行扩容,且可以指定一个固定的扩容增量;ArrayList再进行扩容操作时会将当前容量增大50%。
  3. Vector集合大大部分操作都是线程安全的,但是使用的是synchronized锁,锁的粒度太过粗放,保证线程安全性不推荐使用Vector;ArrayList集合不是线程安全的,在多线程环境下不能使用它。
  4. Vector集合在序列化的过程中,当前elementData数组中多余的索引位被序列化,产生不必要的性能消耗;在对ArrayList集合进行序列化时,只会对elementData数组中已使用的索引位进行序列化,未使用的索引位不会被序列化;相对地,在原ArrayList集合中已被序列化的各个数据对象被反序列化成新的ArrayList集合中的数据对象时,新的elementData数组不会产生多余的容量,只有在下一次被要求向该集合中添加数据对象时,才会开始新一轮的扩容操作。

7.Stack

1.Stack概要

Java集合框架之List
2.Stack和Vector的对比
  1. Stack继承自Vector,内部结构都是数组,都存在数组扩容的问题,每次将数组容量增大一倍的方式不灵活。
  2. 两者都是线程安全的,但是不推荐使用。已经被LinkedBlockingQueue和CopyOnWriteArrayList等替代。
  3. 两者没有针对序列化过程和反序列化过程进行任何优化,而工作效果相似的ArrayDeque集合、ArrayList集合都对序列化过程的反序列化过程进行了优化。

Java集合框架之List
  1. LinkedList底层由双向链表实现
// &#x96C6;&#x5408;LinkedList&#x7684;&#x5BF9;&#x8C61;&#x4E2A;&#x6570;
transient int size = 0;
// &#x6307;&#x5411;&#x5934;&#x8282;&#x70B9;&#xFF08;&#x53CC;&#x5411;&#x94FE;&#x8868;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x8282;&#x70B9;&#xFF09;
transient Node<e> first;
// &#x6307;&#x5411;&#x5C3E;&#x8282;&#x70B9;&#xFF08;&#x53CC;&#x5411;&#x94FE;&#x8868;&#x7684;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#x8282;&#x70B9;&#xFF09;
transient Node<e> first;

// &#x53CC;&#x94FE;&#x8868;&#x8282;&#x70B9;&#x7ED3;&#x6784;
private static class Node<e> {
        // &#x8282;&#x70B9;&#x5B58;&#x50A8;&#x7684;&#x5143;&#x7D20;
        E item;
        // &#x6307;&#x5411;&#x4E0B;&#x4E00;&#x4E2A;&#x8282;&#x70B9;
        Node<e> next;
        // &#x6307;&#x5411;&#x524D;&#x4E00;&#x4E2A;&#x8282;&#x70B9;
        Node<e> prev;
}
</e></e></e></e></e>
  1. linkFirst(E e):在双链表头部插入一个新节点
  2. linkLast(E e):在双链表尾部插入一个新节点
  3. linkBefore(E e, Node succ):在指定节点前插入一个新节点

  4. unlinkFirst(Node f):移除双链表的第一个节点

  5. unlinkLast(Node l):移除双链表的最后一个节点
  6. unlink(Node x):移除双链表的指定节点

  7. 查询指定索引位置的节点

// &#x6839;&#x636E;&#x7D22;&#x5F15;&#x548C;&#x96C6;&#x5408;&#x957F;&#x5EA6;&#x7684;&#x4E00;&#x534A;&#x5BF9;&#x6BD4;&#xFF0C;&#x6765;&#x51B3;&#x5B9A;&#x5728;&#x5934;&#x90E8;&#x8FD8;&#x662F;&#x5C3E;&#x90E8;&#x5F00;&#x59CB;&#x641C;&#x7D22;&#x3002;
Node<e> node(int index) {
    // assert isElementIndex(index);

    if (index < (size >> 1)) {
        Node<e> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<e> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

</e></e></e>
  1. 基于数组结构的ArrayList的删除和插入操作效率不高,需要考虑数组扩容元素复制、移动数组元素的问题;基于双向链表的LinkedList的插入和修改操作需要考虑查询索引位的节点的时间消耗,如果在靠近双向链表的中间位置插入新的节点,则找到正确的索引位置节点的时间复杂度为o(n)。
  2. ArrayList集合支持随机访问,所以查询的效率很高,时间复杂度为O(1);LinkedList集合的查询操作时间复杂度为o(n);

Original: https://www.cnblogs.com/xiaocer/p/16745233.html
Author: 文件精度
Title: Java集合框架之List

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/615919/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • IDEA远程部署项目到Docker

    最近在写东西部署到服务器,结构是springboot工程配合docker部署。但是每次部署都3个步骤: 部署次数一多,我就怀疑人生了。就在找有没有IDEA远程部署Docker的方案…

    Java 2023年6月16日
    084
  • Maven 依赖调解源码解析(二):如何调试 Maven 源码和插件源码

    有了源码包和 Demo 项目,我们就能够着手分析了。那么问题来了,我们对 Maven 源码并不熟悉,总不能一头扎进去看。那么,我们就用调试的方式分析吧,简单且精准。 在 Demo …

    Java 2023年6月16日
    069
  • @RequestBody使用说明

    @RequestBody 使用 @RequestBody这个对于一般刚接触来说,确实有点陌生,但是现在前端,后端技术分的太细,越来越多的技术层出不穷,前端就分化出POST ,GET…

    Java 2023年6月16日
    086
  • 简单聊聊mysql的脏读、不可重复读、幻读

    最近,在一次 mysql 死锁的生产事故中,我发现,关于 mysql 的锁、事务等等,我所知道的东西太碎了,所以,我试着用几个例子将它们串起来。具体做法就是通过不断地问问题、回答问…

    Java 2023年6月14日
    081
  • java技术难点

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年5月29日
    086
  • 第七周总结-vue脚手架整合SSM-路由配置

    使用axios异步 用户列表 编号 姓名 年&#x9F…

    Java 2023年6月7日
    0105
  • spring自动注入是单例还是多例?单例如何注入多例?

    单例多例需要搞明白这些问题: 1. 什么是单例多例; 2. 如何产生单例多例; 3. 为什么要用单例多例 4. 什么时候用单例,什么时候用多例; 1. 什么是单例、多例: 单例模式…

    Java 2023年5月30日
    084
  • protected,default访问限制详解

    posted @2022-09-08 09:35 2337 Views(11 ) Comments() Edit Original: https://www.cnblogs.com…

    Java 2023年6月6日
    0128
  • 正确输出Hello world!

    _ Hello world , 随便新建一个文件夹,存放代码 新建一个java文件 文件后缀名为.java Hello.java 系统可能没有显示文件后缀名,需手动打开 手动打开需…

    Java 2023年6月5日
    078
  • 跟着柴毛毛学Spring(3)——简化Bean的配置

    通过前面的学习。我们会感觉到对于一个有较多Bean的大项目,Spring的配置会比較复杂。 那么接下来我们就介绍怎样简化Spring的配置。 简化Spring的配置主要分为两类:1…

    Java 2023年5月30日
    060
  • 红黑树以及JAVA实现(二)

    红黑树的删除 红黑树的删除相对于插入,会复杂很多。 我们分情况讨论 删除节点为叶子节点 分两种情况,删除节点是红色节点和删除节点为黑色节点 1.1 删除节点为红色节点 如果是红色节…

    Java 2023年6月13日
    072
  • java宝典笔记(一)

    第四章java 基础知识 4.1 基本概念 一、java 优点 1.面向对象(封装、继承、多态) 2.可移植性。平台无关,一次编译,到处运行。Windows ,Linux ,mac…

    Java 2023年6月7日
    077
  • Java 包、包的编译

    Java 包 Java 采用包的概念来对相关的类进行管理。 包可以避免名称冲突,并且通过包名进行分类后,代码的维护性会有所提高。 包本质上就是一个个文件夹 以上都是 Java 的内…

    Java 2023年6月5日
    0100
  • 大文件批量上传断点续传文件秒传

    在上篇中,我们可以使用 file. slice 方法对文件进行分片,可以从后台读到当前文件已经上传的大小,就可以知道从哪里开始切片,断点续传的原理就是基于这个的。 前端计算文件的 …

    Java 2023年6月5日
    093
  • 类的动态装载java

    类的动态装载 首先,我们要明白类加载的过程,再来区分静态加载和动态加载,类加载的过程,本质上就是将类文件,从硬盘读取到内存中的过程,而静态加载是在编译时加载,动态加载是在程序运行时…

    Java 2023年6月5日
    0107
  • 将链表按照左右分区重新排列

    将链表按照左右分区重新排列 问题重述: 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 &#x2192; L1 &#x2192; &#…

    Java 2023年6月7日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球