Java基础_集合类_List

server/2024/9/24 8:06:33/

List

  • Collection、List接口
    • 1、继承结构
    • 2、方法
  • Collection实现类
    • 1、继承结构
    • 2、相关类
      • (1)AbstractCollection
      • (2)AbstractList
        • AbstractSequentialList(子类)
      • 其它接口
        • RandomAccess【java.util】
        • Cloneable【java.lang】
        • Serializable【java.io】
  • 具体实现类
    • 1、Vector
      • Stack
    • 2、ArrayList
    • 3、LinkedList
      • Deque接口(子接口)
        • Queue接口(父接口)
      • 源码分析
    • 4、CopyOnWriteArrayList【COW并发容器,写时复制容器<读写分离>】

Collection、List接口

1、继承结构

在这里插入图片描述

2、方法

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Collection实现类

1、继承结构

在这里插入图片描述
类图:
在这里插入图片描述

2、相关类

(1)AbstractCollection

Collection接口的骨架式实现类,最小化实现Collection接口的代价。

(2)AbstractList

List接口的骨架式实现类,最小化实现List接口的代价。**“随机访问”**数据存储。

提供了iterator()、listIterator()方法的实现。

重要属性
protected transient int modCount;【修改次数,迭代器和列表迭代器使用】
如果该字段的值发生意外变化,迭代器(或列表迭代器)将抛出ConcurrentModificationException,以响应next、remove、previous、set、add操作。这提供了快速故障行为,而不是在迭代期间面对并发修改时的不确定性行为。

AbstractSequentialList(子类)

List接口的框架实现,**“顺序访问”**数据存储。

其它接口

javautil_29">RandomAccess【java.util】


List实现使用的标记接口,表明它们支持快速随机访问(通常是常量时间)

该接口的主要目的是允许泛型算法改变其行为,以便在应用于随机或顺序访问列表时提供良好的性能。

操作随机访问列表(如ArrayList)的最佳算法在应用于顺序访问列表(如LinkedList)时可以产生二次行为。鼓励泛型列表算法在应用算法之前检查给定列表是否是该接口的实例。

javalang_36">Cloneable【java.lang】

标记接口
一个类实现了Cloneable接口,表明调用Object.clone()方法对该类的实例进行逐个字段的复制是合法的。在没有实现Cloneable接口的实例上调用Object的clone方法将导致抛出CloneNotSupportedException异常。

按照约定,实现这个接口的类应该重写Object.clone()方法,表明是public,而Object.clone()方法是protected

这个接口不包含clone方法。因此,不可能仅仅因为对象实现了这个接口就克隆它。即使以反射方式调用clone方法,也不能保证它一定会成功。

javaio_43">Serializable【java.io】

标记接口。Serializable接口没有方法或字段,仅用于标识可序列化的语义。

具体实现类

1、Vector

在这里插入图片描述
在这里插入图片描述

  • 可增长的对象数组,使用索引访问:capacitycapacityIncremnt

Stack

继承自Vector类,扩展Vector类实现LIFO功能:

  • push、pop
  • peek
  • search
  • empty

LIFO功能:
在这里插入图片描述

2、ArrayList

在这里插入图片描述
List接口的可调整数组实现。

不同步

  • Collections.synchronizedList(new ArrayList(…));

实现所有可选列表操作,并允许所有元素,包括null。除了实现List接口之外,这个类还提供了一些方法来操作内部用于存储列表的数组的大小。(大致相当于Vector,但不同步。)

  • Cloneable:Object.clone()

  • Iterable:forEach(Consumer<? super E> action)

  • Collection:removeIf(Predicate<? super E> filter)

  • AbstractList:removeRange(int fromIndex, int toIndex)

  • 增加方法:

    • ensureCapacity(int minCapacity)
    • trimToSize()
      时间复杂度:
  • size、isEmpty、get、set、iterator和listIterator操作在常量时间内运行。

  • add在平摊常数时间内运行,即添加n个元素需要O(n)时间。

  • 所有其他操作都在线性时间内运行(粗略地说)。

与LinkedList实现相比,常数因子较低

每个ArrayList实例都有一个capacity,用于存储列表中元素的数组的大小。它总是至少和列表大小一样大。当元素被添加到ArrayList中时,它的容量会自动增长。
在添加大量元素之前使用ensureCapacity操作来增加ArrayList实例的容量。这可能会减少增量再分配的数量。

分析源码
(1)构造函数

java">//存储数据:Object数组elementData//构造函数(空参):赋值空数组
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}/*构造函数(含参:容器大小):判断initialCapacity > 0:创建对应大小的一个Object数组;= 0 :赋值一个空数组
*/
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);}
}/*构造函数(使用集合Collection的子类对象)
*/
public ArrayList(Collection<? extends E> c) {//将参数转换成数组Object[] a = c.toArray();//数组长度不为0//参数类型判断:ArrayList直接赋值;Arrays.copyOf()方法拷贝if ((size = a.length) != 0) {if (c.getClass() == ArrayList.class) {elementData = a;} else {elementData = Arrays.copyOf(a, size, Object[].class);}} else {//转换的数组长度为0:赋值空数组 elementData = EMPTY_ELEMENTDATA;}
}

(2)数组大小扩展

java">	// 减少不必要的空间消耗public void trimToSize() {//处理数++modCount++;//容器中元素个数 VS 存储数据数组长度 if (size < elementData.length) {//容器空 ? 空数组 : Arrays.copyOf()elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}public void ensureCapacity(int minCapacity) {//minCapacity>底层数组长度【需要扩容】//!(底层数组不空 && minCapacity<=10)【底层数组空:第一次】if (minCapacity > elementData.length&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA && minCapacity <= DEFAULT_CAPACITY)) {//操作数++modCount++;//增加grow(minCapacity);}}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)];}}private Object[] grow() {return grow(size + 1);}

(3)代码

java">ArrayList<String> al = new ArrayList<>();
al.add("hello");

构造函数:创建一个空数组
在这里插入图片描述
add()方法:【底层:空数组】=>扩容到长度为DEFAULT_CAPACITY(10)的数组
在这里插入图片描述
假设当前底层数组中已经添加了10个元素,现在继续调用add()添加一个元素:数组扩容1.5倍
在这里插入图片描述

3、LinkedList

在这里插入图片描述

Deque接口(子接口)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Queue接口(父接口)

在这里插入图片描述
在这里插入图片描述

源码分析

(1)双向链表

java">    private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}transient int size = 0;transient Node<E> first;transient Node<E> last;//构造函数public LinkedList() {}

(2)add方法

java">	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;elsel.next = newNode;size++;modCount++;}

在这里插入图片描述

4、CopyOnWriteArrayList【COW并发容器,写时复制容器<读写分离>】

在这里插入图片描述
在这里插入图片描述

底层:Object数组
在这里插入图片描述


http://www.ppmy.cn/server/20364.html

相关文章

hive创建hbase外部关联表实例

在cdh6.3.2已经做好hbase和hive相关配置&#xff0c;这里不阐述。 要创建上述的表结构&#xff0c;你需要先在HBase中创建相应的表&#xff0c;然后在Hive中创建一个EXTERNAL TABLE来映射到这个HBase表。以下是详细的步骤&#xff1a; 步骤1&#xff1a;在HBase中创建表 确定…

ReactJS中使用TypeScript

TypeScript TypeScript 实际上就是具有强类型的 JavaScript&#xff0c;可以对类型进行强校验&#xff0c;好处是代码阅读起来比较清晰&#xff0c;代码类型出现问题时&#xff0c;在编译时就可以发现&#xff0c;而不会在运行时由于类型的错误而导致报错。但是&#xff0c;从…

GateWay具体的使用之局部过滤器接口耗时

1.找规律 局部过滤器命名规则 XXXGatewayFilterFactory&#xff0c; 必须以GatewayFilterFactory结尾。 /* 注意名称约定 * AddRequestHeaderGatewayFilterFactory 配置的时候写的是 AddRequestHeader * AddRequestParameterGatewayFilterFactory 配置的时候写的是 A…

day04--react中state的简化

一、简化state 回顾我们之前的写法&#xff1a; state是在构造器里面定义的。 1&#xff09;我们为什么要在构造器里面定义&#xff1f; 答&#xff1a;对于创建一个实例对象时&#xff0c;我们对要传进来的数据进行接收&#xff0c;那么我们必须要写一个构造器来接收传进来的…

GCC编译器介绍及编译流程说明

一、计算机基础 1、冯诺依曼模型 1945年冯诺依曼和一些科学家提出了一份报告,报告遵循了图灵机的设计&#xff0c;并提出用电子元件构造计算机&#xff0c;约定了用二进制进行计算和存储&#xff0c;并且将计算机结构分成运算器&#xff0c;控制器、存储器、输入设备、输出设备…

旅游网站制作流程

旅游网站制作流程是一个较复杂的过程&#xff0c;因为它需要结合市场调研、用户需求、内容构建、技术开发等多个方面。在这篇文章中&#xff0c;我将简单介绍一下旅游网站的制作流程&#xff0c;大致分为以下步骤。 第一步&#xff1a;市场调研 在制作旅游网站前&#xff0c;我…

数据结构:实验六:图的操作

一、 实验目的 &#xff08;1&#xff09;掌握图的邻接矩阵和邻接表存储结构。 &#xff08;2&#xff09;熟练图的邻接表的基本运算。 &#xff08;3&#xff09;加深图的深度优先遍历算法和广度优先遍历算法的理解 二、 实验要求 有下图所示的带权有向图及其对应的邻…

探索和构建 LLaMA 3 架构:深入探讨组件、编码和推理技术(十)

探索和构建 LLaMA 3 架构&#xff1a;深入探讨组件、编码和推理技术&#xff08;十&#xff09; Llama 推理 为了对模型进行推理&#xff0c; 需要从Meta的LLaMA 3仓库下载模型的权重。 编写模型推理的代码。在推理模型时&#xff0c;有许多可调参数需要考虑&#xff0c;包括…