百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

能懂系列之 List 集合详解

liuian 2025-01-14 15:19 38 浏览



今天咱们来谈一谈 java 的 list 集合吧,进入正题之前呢,咱们聊点题外话吧。前几天在工作中使用到了 map 的嵌套,也就是一个 map 的 value 是另一个 map, 这个由于是第一次接触呢,所以当时这个逻辑还是比较混乱的,因为不知道如果改了外层的 map , 内层的 value 会不会随之改变,后来做了好几个实例才发现不会,因为外层 map 的 key 所对应的 value 值都是和 key 绑定的,所以其实和一般的 map 的逻辑是一样的,这个等我之后有空的话再详细讲一讲吧。

好了,言归正传吧,下面正式进去今天的主题 --- List

那么,问题来了,什么是 list 呢,list 的特性和使用方法种种的又是什么呢,接下来就让我一点一点的来说吧。

List 是什么?

首先,咱们来说说什么是 List 吧!

集合类是 Java 数据结构的实现。Java 的集合类是 java.util 包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java 集合类是 Java 将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。

以上,是百度百科对于 List 集合的说明。通俗地讲 List 就是一个存放数据的容器,他根据你存储的顺序来给对应的索引值,而索引呢,也是你用来取出值的一个标识。

List 的继承结构

List 的继承结构

上面那张图没有过多的花里胡哨,可以让我们很清晰的看出集合的一个大概的继承体系,然而我们今天只看 Collection 下的 list 接口以及其实现类,因为我们今儿就是研究它来了。

特有功能

List 集合是一个元素有序(每个元素都有对应的顺序索引,第一个元素索引为 0)、且可重复的集合。

List 是 Collection 接口的子接口,故而拥有 Collection 的所有方法。除此之外呢,还有一些对索引操作的方法。

今天我们主要说的还是 List 的实现类,毕竟它很常用。

List 整体

从上图,可以让我们对于 List 的三个实现类有一个大概的了解.

分类

1、ArrayList

ArrayList 是一个数组队列,相当于 「动态数组」。与 Java 中的数组相比,它的容量能动态增长。它继承于 AbstractList,实现了 List, RandomAccess(随机访问), Cloneable(克隆), java.io.Serializable(可序列化)这些接口.

ArrayList 继承了 AbstractList,实现了 List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能.

ArrayList 实现了 RandmoAccess 接口,即提供了随机访问功能。RandmoAccess 是 java 中用来被 List 实现,为 List 提供快速访问功能的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问.

ArrayList 实现了 Cloneable 接口,即覆盖了函数 clone (),能被克隆。ArrayList 实现 java.io.Serializable 接口,这意味着 ArrayList 支持序列化,能通过序列化去传输.

ArrayList 的底层数据结构因为是数组,故而查询快,增删慢,线程不安全,效率高,可以存储重复元素。下面来看看 ArrayList 常用的一些方法吧。

1.1、add 方法:

向集合中插入数据,集合的索引下标是从 0 开始.

1.2、插入数据

向指定位置插入数据,两个参数,一个是索引,一个是数据,插入后这个索引后面的数据向后顺延.

1.3、删除数据

删除集合中的数据,参数是数据对应的索引值.

1.4、返回索引值.

指定元素再 list 集合中的位置,返回索引值.

1.5、set

替换 List 中对应位置的值,两个参数分别是索引及新的数据,此操作的返回值是被替换的数据.

1.6、get

返回指定索引的数据

1.7、addAll

新增集合操作,两个参数:插入的位置索引,插入的集合

1.8、lastIndexOf

返回元素最后一次出现的位置索引

1.9、subList

截取指定位置的数据,两个参数:开始位置的索引,结束位置的索引

上面所有代码的运行结果如下图:

好了,相信讲完这些大家会对 ArrayList 的使用有了一些比较具体的了解了。

不过厚此薄彼不好,下面我们来说说 List 的另外两个实现类吧,不过主要就是说一下它们和 ArrayList 的一个区别及它们本身的优势吧.

2、LinkedList

LinkedList 可以看做为一个双向链表,所有的操作都可以认为是一个双向链表的操作,因为它实现了 Deque 接口和 List 接口。同样,LinkedList 也是线程不安全的,如果在并发环境下使用它,同样用 Colletions 类中的静态方法 synchronizedList () 对 LinkedList 进行调用即可. LinkedList 与 ArrayList 最大的区别是 LinkedList 更加灵活,并且部分方法的效率比 ArrayList 对应方法的效率要高很多,对于数据频繁出入的情况下,并且要求操作要足够灵活,建议使用 LinkedList;对于数组变动不大,主要是用来查询的情况下,可以使用 ArrayList。

LinkedList 常用方法:

  • toArray (): 以正确的顺序(从第一个到最后一个)返回一个包含此列表中所有元素的数组
  • size (): 返回此列表中的元素数
  • set (int index,E element): 用指定的元素替换此列表中指定位置的元素
  • removeLast (): 从此列表中删除并返回最后一个元素
  • removeFirst (): 从此列表中删除并返回第一个元素
  • remove (int index): 删除该列表中指定位置的元素
  • getFirst (): 返回此列表中的第一个元素
  • getLast (): 返回此列表中的最后一个元素
  • get (int index): 返回此列表中指定位置的元素
  • add (E element): 将指定的元素追加到此列表的末尾
  • add (int index,E element): 在此列表中的指定位置插入指定的元素
  • addFirst (E element): 在该列表开头插入指定的元素
  • addLast (E element) : 将指定的元素追加到此列表的末尾
  • clear (): 从列表中删除所有元素

3、Vector

Vector 也是一个类似于 ArrayList 的可变长度的数组类型,它的内部也是使用数组来存放数据对象的。值得注意的是 Vector 与 ArrayList 唯一的区别是,Vector 是线程安全的,即它的大部分方法都包含有关键字 synchronized. 因此,若对于单一线程的应用来说,最好使用 ArrayList 代替 Vector,因为这样效率会快很多(类似的情况有 StringBuffer 与 StringBuilder);而在多线程程序中,为了保证数据的同步和一致性,可以使用 Vector 代替 ArrayList 实现同样的功能.「Vector 常用方法:」

  • add (E element): 将指定的元素追加到此 Vector 的末尾
  • add (int index,E element):在此 Vector 中的指定位置插入指定的元素
  • elementAt (int index): 返回指定索引处的组件
  • get (int index): 返回此向量中指定位置的元素
  • removeElementAt (int index): 删除指定索引处的组件
  • removeRange (int fromIndex,int toIndex):从此列表中删除所有索引为 fromIndex (含)和 toIndex 之间的元素

上面大体说了说 List 集合中另外两种实现类的一些基本详情,最后,既然是一系列的数据,那么必然会面临一个遍历的问题,所有本文的最后我们来看一看 List 的遍历方式 (其实只是 ArrayList 的遍历方式).

3.1、通过迭代器遍历。即通过 Iterator 去遍历.

List<String> list = new ArrayList();
        list.add(new String("book001"));
        list.add(new String("book002"));
        list.add(new String("book003 "));
        String value = null;
        Iterator iter = list.iterator();
        while (iter.hasNext()) {
            value = (String)iter.next();
            System.out.println(value);
        }

结果展示:

3.2、随机访问 index, 通过索引值去遍历.

由于 ArrayList 实现了 RandomAccess 接口,它支持通过索引值去随机访问元素.

List<String> list = new ArrayList();
        list.add(new String("book004"));
        list.add(new String("book005"));
        list.add(new String("book006 "));
        String value = null;
        int size = list.size();
        for (int i=0; i<size; i++) {
            value = (String)list.get(i);
            System.out.println(value);
        }

结果展示:

3.3、增强 for (foreach) 循环遍历

List<String> list = new ArrayList();
        list.add(new String("book007"));
        list.add(new String("book008"));
        list.add(new String("book009"));
        String value = null;
        for (String books:list) {
            value = books;
            System.out.println(value);
        }

结果展示:

小结

List 中元素是有序的,元素可以重复,因为该集合体有索引

ArrayList:

  • 底层数据结构是数组,查询快,增删慢。
  • 线程不安全,效率高。
  • 当元素放满了后,默认以原长度的 50%+1 的长度加长集合容器的长度。

LinkedList:

  • 底层数据结构是链表,查询慢,增删快。
  • 线程不安全,效率高。
  • Vector (线程安全的) 相对 ArrayList 查询慢
  • Vector 相对 LinkedList 增删慢 (数组结构)

Vector:

  • 底层数据结构是数组,查询快,增删慢。
  • 线程安全,效率低。
  • 当元素放满了后,默认以原长度 100% 的长度加长集合容器的长度

好啦,今天的关于 list 集合的一些知识就讲解结束啦,有什么错误或不足欢迎大家留言指正,程序员的路上并肩前行吧。

作者丨阿淼

来源丨微信公众号:Java学习之道

相关推荐

Docker 47 个常见故障的原因和解决方法

【作者】曹如熙,具有超过十年的互联网运维及五年以上团队管理经验,多年容器云的运维,尤其在Docker和kubernetes领域非常精通。Docker是一种相对使用较简单的容器,我们可以通过以下几种方式...

电脑30个快问快答,解决常见电脑问题

1.强行关机/停电对电脑有影响吗?答:可能损坏硬盘(机械硬盘风险高)、未保存数据丢失,偶尔一次影响小,但频繁操作会缩短硬件寿命。2.C盘满影响速度吗?答:会!系统运行需C盘空间缓存临时数据,空间不...

使用Tcpdump包抓取分析数据包的详细用法

TcpDump可以将网络中传送的数据包的“头”完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来帮助你去掉无用的信息。tcpdump就是一种...

电脑启动不了(BootDevice Not Found Hard Disk-3F0)解决方案

HP品牌机,开机启动不了,黑屏,开机取下主板电池恢复BIOS后,开机显示找不到启动盘。一、按F2键进入BIOS,出现硬盘内存检测界面的话,直接退出。就会出现这个界面,光标键向下,选择BIOSSetu...

电脑开机黑屏别慌!快码住!起底维修老师傅不能说的秘密

按下开机键却只收获黑屏大礼包?那些神秘的英文提示、刺耳的蜂鸣声,其实是电脑在给你发送求救信号!从按下电源到进入桌面的12秒里,你的电脑经历了史诗级的硬件自检与系统加载,今天我们就破译这段“摩斯电码”。...

电脑启动故障为何总要先看BIOS?新手必读的关键知识解析

最近在帮朋友们解答电脑无法正常开机的问题时,发现大家经常收到一句高频建议:“先检查BIOS”。对不少普通用户而言,BIOS依然是个神秘的存在。那么,BIOS到底是什么?电脑出现哪些故障会与它相关呢?本...

Windows 11 KB5053598更新:安全补丁还是系统噩梦?

2025年3月11日,微软发布了Windows1124H2的强制性更新KB5053598,作为“周二补丁日”(PatchTuesday)的一部分。然而,这款本应提升系统安全性的更新却引发了广泛的...

飞牛OS入门安装遇到问题,如何解决?

之前小编尝试了用旧电脑装飞牛OS安装之前特意查了一些硬件要求飞牛OS目前支持主流的x86架构硬件主机需能连网线飞牛OS暂时不支持只有无线网卡的安装貌似很多小伙伴在一开始安装就卡住了那今天咱们汇总分...

几种常见的电脑开机黑屏显示白色英文字母解决方法

当电脑开机出现黑屏并显示白色英文字母时,通常表示系统启动过程中遇到了错误。以下是几种常见原因及对应的解决方法,按照排查顺序整理:一、检查外接设备与硬件连接可能原因:外接U盘、移动硬盘等未拔出,或内部硬...

电脑启动出现问题,为什么都要先检查BIOS?

【ZOL中关村在线原创技巧应用】最近在回答问题的时候,总会发现很多朋友都在问“电脑无法正常开机怎么办?”这样类似的问题,而许多DIY大佬的回复总会出现一条高频建议“先检查BIOS”。但对于许多普通用户...

教你怎么用JavaScript检测当前浏览器是无头浏览器

什么是无头浏览器(headlessbrowser)?无头浏览器是指可以在图形界面情况下运行的浏览器。我可以通过编程来控制无头浏览器自动执行各种任务,比如做测试,给网页截屏等。为什么叫“无头”浏览器?...

12个高效的Python爬虫框架,你用过几个?

实现爬虫技术的编程环境有很多种,Java、Python、C++等都可以用来爬虫。但很多人选择Python来写爬虫,为什么呢?因为Python确实很适合做爬虫,丰富的第三方库十分强大,简单几行代码便可实...

运维的报表之路,用 node.js 轻松发送 grafana 报表

在运维过程中,无论是监控还是报表,都会有一些通过邮件发送图表的需求,由于开源的zabbix,grafana和kibana等并不完全具有“想发送哪儿就发送哪儿”的图片生成功能,在grafana...

C#基于浏览器内核的高级爬虫(c#爬取网页内容)

基于C#.NET+PhantomJS+Sellenium的高级网络爬虫程序。可执行Javascript代码、触发各类事件、操纵页面Dom结构、甚至可以移除不喜欢的CSS样式。很多网站都用Ajax动态加...

如何优化一个秒杀项目?(秒杀实现思路)

问题1:使用jmeter性能压测,定位瓶颈代码步骤流程:线程组--->Http请求--->查看结果树--->聚合报告tips:host的文件--->优先调用映射,减少DNS的时...