Java基础_集合类_List

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接口的框架实现,**“顺序访问”**数据存储。

其它接口

RandomAccess【java.util】


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

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

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

Cloneable【java.lang】

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

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

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

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)构造函数

//存储数据: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)数组大小扩展

	// 减少不必要的空间消耗
	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)代码

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

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

3、LinkedList

在这里插入图片描述

Deque接口(子接口)

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

Queue接口(父接口)

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

源码分析

(1)双向链表

    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方法

	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++;
        modCount++;
    }

在这里插入图片描述

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/579765.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一键PDF水印添加工具

一键PDF水印添加工具 引言优点1. 精准定位与灵活布局2. 自由旋转与透明度调控3. 精细化页码选择4. 全方位自定义水印内容5. 无缝整合工作流程 功能详解结语工具示意图【工具链接】 引言 PDF作为最常用的文档格式之一&#xff0c;其安全性和版权保护显得尤为重要。今天&#xff…

MyBatis面试题总结,详细(2024最新)

面试必须要看看 1、MyBatis 中的一级缓存和二级缓存是什么&#xff1f;它们的区别是什么&#xff1f; MyBatis 中的一级缓存是指 SqlSession 对象内部的缓存&#xff0c;它是默认开启的。一级缓存的生命周期是与 SqlSession 对象绑定的&#xff0c;当 SqlSession 关闭时&#…

vue3 ——笔记 (条件渲染,列表渲染,事件处理)

条件渲染 v-if v-if 指令用于条件性地渲染一块内容&#xff0c;只有v-if的表达式返回值为真才会渲染 v-else v-else 为 v-if 添加一个 else 区块 v-else 必须在v-if或v-else-if后 v-else-if v-else-if 是v-if 的区块 可以连续多次重复使用 v-show 按条件显示元素 v-sh…

8 Dubbo 应用案例(动手实操一波)

概述 案例相关配置可参考 GitHub:https://github.com/apache/dubbo-spring-boot-project/tree/master/dubbo-spring-boot-samples 创建服务接口项目 创建一个名为 hello-dubbo-service-user-api 的项目,该项目只负责定义接口 POM <?xml version="1.0" enco…

28.Gateway-网关过滤器

GatewayFilter是网关中提供的一种过滤器&#xff0c;可以多进入网关的请求和微服务返回的响应做处理。 GatewayFilter(当前路由过滤器&#xff0c;DefaultFilter) spring中提供了31种不同的路由过滤器工厂。 filters针对部分路由的过滤器。 default-filters针对所有路由的默认…

OpenCV如何实现背投

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV直方图比较 下一篇 :OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 目标 在本教程中&#xff0c;您将学习&#xff1a; 什么是背投以及它为什么有用如何使用 Ope…

GraspNet-1Billion 论文阅读

文章目录 GraspNet-1Billion总体数据集评价指标网络pointnet&#xff1a;Approach Network:Operation Network&#xff1a;Tolerance Network 摘要相关工作基于深度学习的抓取预测算法抓取数据集点云深度学习 GraspNet-1Billion CVPR2020 上海交大 论文和数据集地址&#xff1…

【漏洞复现】艺创科技智能营销路由器后台命令执行漏洞

漏洞描述&#xff1a; 成都艺创科技有限公司是一家专注于新型网络设备研发、生产、销售和服务的企业&#xff0c;在大数据和云时代&#xff0c;致力于为企业提供能够提升业绩的新型网络设备。 智能营销路由器存在后台命令执行漏洞&#xff0c;攻击者可利用漏洞获取路由器控制…

Android 开发工具使用

c调试 在NDK调试的时候&#xff0c;如果找不到 符号的话&#xff0c;我们可以在调试配置中添加符号地址的全路径一直到根目录&#xff1a;&#xff0c;xxx/armeabi-v7a&#xff1a; You must point the symbol search paths at the obj/local/ directory. This is also not a …

1146. 快照数组

java版本 class SnapshotArray {int id 0;List<int[]>[] snapshots;public SnapshotArray(int length) {snapshots new List[length];for (int i 0; i < length; i) {snapshots[i] new ArrayList<int[]>();}}public void set(int index, int val) {snapsho…

运算符重载(1)

1.加号运算符重载&#xff0c;这里用编译器统一的名称operator代替函数名 #include<iostream> using namespace std; //1.成员函数的加号重载 //2.全局函数的加号重载 class Person { public:Person() {};//1.成员函数的加号重载//Person operator(Person& p)//{// P…

E4980A是德科技E4980A精密LCR表

181/2461/8938产品概述&#xff1a; Keysight E4980A 精密 LCR 表为各种元件测量提供了精度、速度和多功能性的最佳组合。E4980A 在低阻抗和高阻抗范围内提供快速测量速度和出色的性能&#xff0c;是元件和材料的一般研发和制造测试的终极工具。LAN、USB 和 GPIB PC 连接可提高…

Springboot实现国际化以及部署Linux不生效问题

1、在application.properties 添加以下配置&#xff1a; #国际化配置 spring.messages.basenamei18n/messages/messages spring.messages.fallback-to-system-localefalse 2、添加配置文件在 resources目录下 如下图所示&#xff1a; 这个国际化文件命名有个坑&#xff0c;必须…

校车车载4G视频智能监控系统方案

一、项目背景 随着社会的快速发展&#xff0c;校车安全问题日益受到人们的关注。为了提高校车运营的安全性&#xff0c;保障学生的生命安全&#xff0c;我们提出了一套校车车载4G视频智能监控系统方案。该系统能够实时监控校车内部和外部环境&#xff0c;及时发现并处理潜在的…

多线程模型浅谈

优质博文&#xff1a;IT-BLOG-CN 笔者近期在维护的项目中发现了一些比较随机的问题&#xff0c;时有时无的&#xff0c;排查之后发现是使用多线程导致的&#xff0c;恍然之下研究了下多线程的底层模型相关知识&#xff0c;现不大家简要分享下。 一个程序进程可包含多个线程&am…

统计建模——模型——python为例

统计建模涵盖了众多数学模型和分析方法&#xff0c;这些模型和方法被广泛应用于数据分析、预测、推断、分类、聚类等任务中。下面列举了一些常见的统计建模方法及其具体应用方式&#xff1a; 目录 1.线性回归模型&#xff1a; ----python实现线性回归模型 -------使用NumPy…

牛客网刷题 | BC66 牛牛的通勤

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 牛牛的通勤路上有两…

yolov8旋转目标检测输出的角度转化为适合机械爪抓取的角度

1. 机械爪抓取时旋转的角度定义 以X轴正方向&#xff08;右&#xff09;为零度方向&#xff0c;角度取值范围[-90&#xff0c;90)。 确认角度的方法&#xff1a; 逆时针旋转X轴&#xff0c;X轴碰到矩形框长边时旋转过的角度记为angleX&#xff1a; 1.如果angleX小于90&#xf…

udp/tcp错误总结

udp tcp——多进程 tcp——多线程 tcp——线程池 tcp——守护进程 &#x1f386;udp  ✨pthread_create 错误总结  ✨LockGuard错误总结  ✨服务端需要写成多线程  ✨客户端也需要写成多线程  ✨多线程调试工具 &#x1f386;tcp  ✨tcp独有调试工具——telnet  ✨Threa…

Python的历史演变与作用

目录 1.概述 2.起源 3.发展阶段 4.Python 3的诞生 5.现状与未来 6.Python的作用 6.1.Web开发 6.2.数据科学与人工智能 ​​​​​​​6.3.自动化与脚本编程 ​​​​​​​6.4.教育与学习 ​​​​​​​6.5.其他领域 7.结语 1.概述 Python&#xff0c;一门富有表…
最新文章