List 接口常用实现类底层分析

一、集合

1.1 简介

        集合主要分为两组(单列集合、双列集合),Collection 接口有两个重要的子接口 List Set,它们的实现子类都是单列集合。Map 接口的实现子类是双列集合,存放的是 K-V

1.2 关系图

二、Collection 接口和常用方法

public interface Collection<E> extends Iterator<E>

2.1 特点

        1、Collection 实现子类可以存放多个元素,每个元素可以是 Object

        2、有些 Collection 的实现类可以存放重复元素,有些不可以。

        3、有些 Collection 的实现类是有序的(List),有些不是有序的(Set

        4、Collection 接口没有直接的实现子类,是通过它的子接口 Set List 来实现的

2.2 常用方法

        下面使用实现类 ArrayList 来演示,如下

public class CollectionTest {public static void main(String[] args) {Collection list = new ArrayList();// add: 添加单个元素list.add("java");list.add(10);list.add(true);System.out.println("list="+list);// remove: 删除指定元素list.remove(true);System.out.println("list="+list);// contains: 查找元素是否存在System.out.println(list.contains("java"));// size: 获取元素个数System.out.println("现在集合的大小为:"+list.size());// isEmpty: 判断是否为空System.out.println("判断集合是不是空的"+list.isEmpty());// clear: 清空集合list.clear();System.out.println("我要清空集合了,现在集合的大小为:"+list.size());// addAll: 添加多个元素ArrayList list2 = new ArrayList();list2.add("苹果");list2.add("香蕉");list.addAll(list2);System.out.println("添加完多个元素后集合的大小为:"+list.size());// containsAll: 查找多个元素是否都存在System.out.println("查找多个元素是否都存在:"+list.containsAll(list2));// removeAll: 删除多个元素list.removeAll(list2);System.out.println("删除多个元素后集合的大小为:"+list.size());}
}

2.3 接口遍历

2.3.1 Iterator 方式

        Iterator 对象称为迭代器,主要用于遍历 Collection 集合中的元素。所有实现了 Collection 接口的集合类都有一个 iterator() 方法,用于返回一个实现了 Iterator 接口的对象,即可以返回一个迭代器。

        需要注意的是,在调用 iterator.next() 方法之前必须要调用 iterator.hasNext() 方法进行检测,若不调用最终会报异常。

        如果希望再次遍历,则需要重置我们的迭代器,即重新调用下 coll.iterator() 方法即可。

// 得到一个集合的迭代器
Iterator iterator = coll.iterator();
// 判断是否还有下一个元素
while(iterator.hasNext()){// next() 方法有两个作用:下移并且将下移以后集合位置上的元素返回System.out.println(iterator.next());
}

2.3.2 for 循环方式

        增强 for 循环,可以代替 iterator 迭代器。它就是简化版的 iterator,本质是一样的,只能用于遍历集合或数组。

for(元素类型 元素名:集合或数组名){// 访问元素
}

三、List 接口和常用方法

3.1 特点

        1、List 集合类中元素有序(即添加顺序和取出顺序是一致的)、且可重复。

        2、List 集合中每个元素都有其对应的顺序索引,即支持索引。

        3、List 容器中的元素都对应一个整数型的序号记录其在容器中的位置,可以根据序号存取容器中的元素。

3.2 常用实现类

        ArrayListLinkedListVector

3.3 常用方法

public class ListMethod {public static void main(String[] args) {List list = new ArrayList();list.add("苹果");list.add("香蕉");// add(int index,Object ele): 在 index 位置插入 ele 元素list.add(1,"西瓜");System.out.println("list="+list);// addAll(int index,Collection els):从 index 位置开始将 els 中的所有元素添加进来List list2 = new ArrayList();list2.add("足球");list2.add("篮球");list.addAll(0,list2);System.out.println("list="+list);// Object get(int index):获取指定 index 位置的元素System.out.println(list.get(0));// int indexOf(Object obj):返回 obj 在集合中首次出现的位置System.out.println(list.indexOf("足球"));// int lastIndexOf(Object obj):返回 obj 在集合中末次出现的位置System.out.println(list.lastIndexOf("篮球"));// Object remove(int index):移除指定 index 位置的元素,并返回此元素System.out.println(list.remove(0));// Object set(int index,Object obj):设定指定 index 位置的元素为 obj,相当于是替换list.set(2,"美女");System.out.println("list="+list);// List subList(int fromIndex,int toIndex):返回从 fromIndex 到 toIndex 位置的子集合,左闭右开List list3 = list.subList(2,3);System.out.println("list3="+list3);}
}

3.4 排序方法

// 按照 Book 类的 price 属性从小到大排序
public static void sort(List list){int size = list.size();for(int i=0;i<size-1;i++){for(int j=0;j<list.size()-1-i;j++){Book b1 = (Book)list.get(j);Book b2 = (Book)list.get(j+1);if(b1.getPrice()> b2.getPrice()){list.set(j,b2);list.set(j+1,b1);}}}
}

四、ArrayList 

4.1 特点

        ArrayList 可以添加 null,并且可以存储多个。底层是由数组来实现数据存储的,ArrayList 基本等同于 Vector,但是 ArrayList 是线程不安全的。

        ArrayList 中维护了一个 Object 类型的数组 elementData,如下:

// transient 表示该属性不会被序列化
transient Object [] elementData

4.2 无参扩容分析

        当创建 ArrayList 对象时,如果使用的是无参的构造器,则初始化 elementData 容量为 0,第一次添加元素的时候,elementData 会扩容为 10,如需要再次扩容,则扩容 elementData 1.5 倍。

public class ArrayListTest {public static void main(String[] args) {// 使用无参构造器创建 ArrayList 对象// 创建一个容量为 0 的 elementData 数组ArrayList list = new ArrayList();for(int i=1;i<=10;i++){// add() 方法:先判断是否需要扩容,然后再执行赋值// 如果进行扩容,则第一次扩容为10,第二次即以后按照 1.5 倍扩容list.add(i);}for(int i=11;i<=15;i++) {// 此时要进行第二次扩容为: 10+10/2 = 15list.add(i);}// 此时要进行第三次扩容为: 15+15/2=22list.add(100);list.add(200);list.add(null);}
}

4.3 有参扩容分析

        如果使用的是指定大小的构造器,则初始 elementData 容量为指定大小,如果需要扩容,则直接扩容 elementData 1.5 倍。

public class ArrayListTest2 {public static void main(String[] args) {// 使用有参构造器创建 ArrayList 对象// 创建一个容量为 8 的 elementData 数组ArrayList list = new ArrayList(8);for(int i=1;i<=10;i++){// add() 方法:先判断是否需要扩容,然后再执行赋值// 当 i=9 的时候需要进行扩容,此时按照 1.5 倍扩容:8+8/2 = 12list.add(i);}for(int i=11;i<=15;i++) {// 当 i=13 的时候,此时要进行第二次扩容为: 12+12/2 = 18list.add(i);}list.add(100);list.add(200);list.add(null);}
}

五、Vector

5.1 特点

        Vector 底层也是一个对象数组,它是线程安全,Vector 类的操作方法带有 synchronized 关键字修饰。当涉及到线程安全时,可以使用 Vector

5.2 无参扩容分析

        当创建 Vector 对象时,如果使用的是无参的构造器,则初始化 elementData 容量为 10,满了之后,扩容为 elementData  2 倍。

public class VectorTest {public static void main(String[] args) {// 使用无参构造器创建 Vector 对象// new Vector() 时会创建一个容量为 10 的 elementData 数组Vector list = new Vector();for(int i=1;i<=10;i++){// add() 方法:先判断是否需要扩容,然后再执行赋值list.add(i);}// 此时要进行第二次扩容为: 10+10=20list.add(100);}
}

5.3 有参扩容分析

        如果使用的是指定大小的构造器,则初始 elementData 容量为指定大小,满了之后,扩容为 elementData  2 倍。

public class VectorTest {public static void main(String[] args) {// 使用有参构造器创建 Vector 对象// new Vector() 时会创建一个容量为 7 的 elementData 数组Vector list = new Vector(7);for(int i=1;i<=10;i++){// add() 方法:先判断是否需要扩容,然后再执行赋值// 当 i=8 的时候需要进行第一次扩容,容量为:7+7= 14list.add(i);}list.add(100);}
}

六、LinkedList

6.1 特点

        LinkedList 底层实现了双向链表和双端队列的特点,可以添加任意元素,包括 null,线程不安全,没有实现同步。

6.2 底层结构

        1、LinkedList 底层维护了一个双向链表。

        2、LinkedList 中维护了两个属性 first last 分别指向首节点和尾节点。

        3、每个节点(Node 对象),里面又维护了 prevnextitem 三个属性,其中通过 prev 指向前一个,通过 next 指向后一个节点。最终实现双向链表。

        4、所以 LinkedList 的元素的添加和删除不是通过数组完成的,相对来说效率较高。

6.3 LinkedList 和 ArrayList 比较

底层结构增删的效率改查的效率
ArrayList可变数组较低,数组扩容较高
LinkedList双向链表较高,通过链表追加较低

如何选择 ArrayList LinkedList

        1、如果我们增删的操作多,选择 LinkedList

        2、如果我们改查的操作多,选择 ArrayList

        3、一般来说,在程序中,80%90% 都是查询,因此大部分情况下会选择 ArrayList

        4、在一个项目中,根据业务灵活选择,有可能是一个模块使用的是 ArrayList,另外一个模块是 LinkedList。也就是说,要根据业务来进行选择

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openLayers--绘制多边形、获取视图的中心点、获取当前地图等级、设置地图等级

openLayers绘制多边形、获取视图中心点 前言效果图1、导入LineString2、创建添加多边形3、定义多变形样式4、获取当前视图的中心点5、获取当前视图等级6、设置地图等级 前言 上一篇文章在vue项目中绘制了openlayers绘制了地图和标记点&#xff0c;本篇文章讲解openlayers绘制多…

【IDEA使用maven package时,出现依赖不存在以及无法从仓库获取本地依赖的问题】

Install Parent project C:\Users\lxh\.jdks\corretto-1.8.0_362\bin\java.exe -Dmaven.multiModuleProjectDirectoryD:\学习\projectFile\study\study_example_service "-Dmaven.homeD:\Program Files\JetBrains\IntelliJ IDEA2021\plugins\maven\lib\maven3" "…

独创改进 | RT-DETR 引入双向级联特征融合结构 RepBi-PAN | 附手绘结构图原图

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 文章目录 YOLOv6贡献RepBi-…

vuepress使用及拓展(骚操作)

官网 文章目录 背景问题思考方案思索实现方案实现结果存在问题 背景 当前开放平台文件静态保存在前端项目&#xff0c;每次修改都需要通过修改文件发版的方式&#xff0c;很不便利。 1、需要前端手动维护 2、每次小的修改都要发版 随着对接业务的增多&#xff0c;对接文档的变…

【教3妹学编程-算法题】117. 填充每个节点的下一个右侧节点指针 II

2哥 : 3妹&#xff0c;听说你昨天去面试了&#xff0c;怎么样啊&#xff1f; 3妹&#xff1a;嗨&#xff0c;别提了&#xff0c;让我回去等通知&#xff0c;估计是没有通知了&#xff0c; 还浪费我请了一天假。 2哥 : 你又请假了啊&#xff0c; 你是怎么跟你那个严厉的老板请假…

一天写一个(前端、后端、全栈)个人简历项目(附详源码)

一、项目简介 此项目是用前端技术HTMLCSSjquery写的一个简单的个人简历项目模板&#xff0c;图片可点击放大查看&#xff0c;还可以直接下载你的word或者PDF的简历模板。 如果有需要的同学可以直接拿去使用&#xff0c;需自行填写个人的详细信息&#xff0c;发布&#xff0c;…

ChinaSoft 论坛巡礼 | CCF-华为胡杨林基金-系统软件专项(海报)论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…

自动驾驶学习笔记(六)——Apollo安装

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 Apollo安装 硬件配置 安装Ubuntu…

手机转接器实现原理,低成本方案讲解

USB-C PD协议里&#xff0c;SRC和SNK双方之间通过CC通信来协商请求确定充电功率及数据传输速率。当个设备需要充电时&#xff0c;它会发送消息去给适配器请求充电&#xff0c;此时充电器会回应设备的请求&#xff0c;并告知其可提供的档位功率&#xff0c;设备端会根据适配器端…

USB PD v1.0快速充电通信原理

1 原理 本篇文章讲的快速充电是指USB论坛所发布的USB Power Delivery快速充电规范&#xff08;通过VBUS直流电平上耦合FSK信号来请求充电器调整输出电压和电流的过程&#xff09;&#xff0c;不同于本人发布的另一篇文章所讲的高通Quick Charger 2.0规范&#xff0c;因为高通QC…

虹科示波器 | 汽车免拆检修 | 2012 款上汽大众帕萨特车 发动机偶尔无法起动

一、故障现象 一辆2012款上汽大众帕萨特车&#xff0c;搭载CFB发动机&#xff0c;累计行驶里程约为12万km。车主反映&#xff0c;将点火开关置于起动挡&#xff0c;偶尔只能听到“咔哒”一声&#xff0c;起动机没有反应&#xff0c;类似蓄电池亏电时起动发动机的现象。为此&…

【广州华锐互动】VR历史古城复原:沉浸式体验古代建筑,感受千年风华!

在科技日新月异的今天&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经成为了我们生活中不可或缺的一部分。从娱乐游戏到医疗健康&#xff0c;从教育培训到房地产销售&#xff0c;VR技术的应用领域日益广泛。而近年来&#xff0c;VR技术在文化遗产保护和古迹复原方面的…

多模态论文阅读之VLMo

VLMo泛读 TitleMotivationContributionModelExpertimentsSummary Title VLMo:Unified Vision_Langugae Pre-Training with Mixture-of-Modality-Experts Motivation CLIP和ALIGN都采用dual-encoder的方式分别编码图像和文本&#xff0c;模态之间的交互采用cosine similarity…

力扣:有效的括号

自己编写的代码 。 自己的思路&#xff1a; class Solution { private:unordered_map<char,int>symbolValues{{(,1},{),2},{{,4},{},5},{[,8},{],9}, };public:bool isValid(string s) {bool flagfalse;int lenss.length();if (lens % 2 ! 0){flag false;}for…

通过51单片机控制28byj48步进电机按角度正反转旋转

一、前言 本项目基于STC89C52单片机&#xff0c;通过控制28BYJ-48步进电机实现按角度正反转旋转的功能。28BYJ-48步进电机是一种常用的电机&#xff0c;精准定位和高扭矩输出&#xff0c;适用于许多小型的自动化系统和机械装置。 在这个项目中&#xff0c;使用STC89C52单片机…

QT 实现解密m3u8文件

文章目录 概要如何解密M3U8文件呢实现思路和代码序列图网络请求解密 结论 概要 视频文件很多已M3U8文件格式来提供&#xff0c;先复习下什么是M3U8文件&#xff01;用QT的 mutimedia框架来播放视频时&#xff0c;有的视频加载慢&#xff0c;有的视频加载快&#xff0c;为啥&am…

K8s:部署 CNI 网络组件+k8s 多master集群部署+负载均衡及Dashboard k8s仪表盘图像化展示

目录 1 部署 CNI 网络组件 1.1 部署 flannel 1.2 部署 Calico 1.3 部署 CoreDNS 2 负载均衡部署 3 部署 Dashboard 1 部署 CNI 网络组件 1.1 部署 flannel K8S 中 Pod 网络通信&#xff1a; ●Pod 内容器与容器之间的通信 在同一个 Pod 内的容器&#xff08;Pod 内的容…

Android性能优化--Perfetto用SQL性能分析

Android性能优化–Perfetto用SQL性能分析 文章目录 Android性能优化--Perfetto用SQL性能分析介绍Perfetto SQL 基础使用 Perfetto SQL 进行性能分析总结 本文首发地址 https://blog.csdn.net/CSqingchen/article/details/134167741 最新更新地址 https://gitee.com/chenjim/che…

闯关打卡小程序的效果如何

闯关打卡是一种以任务关卡为基础的打卡模式&#xff0c;管理员可配置活动任务关卡&#xff0c;成员加入任务后需依次解锁&#xff0c;打卡完成任务&#xff0c;像闯关游戏一样完成所有任务。 通过打卡活动聚集一群有共同目标、兴趣的人&#xff0c;通过打卡的方式促进共同目标…

对Java的多线程的理解

说说对Java线程的理解 下面是AI的回答 Java线程就是Java程序里面可以同时运行多个任务。Java提供了几种创建和管理线程的方式&#xff0c;其中一种是继承Thread类&#xff0c;另一种是实现Runnable接口或Callable接口。jdk5提供了线程池&#xff0c;可以更方便地创建、启动和终…