List 接口

news2024/11/27 2:47:28

1 List 接口

java.util 中的集合类包含 Java 中某些最常用的类。最常用的集合类是 List 和 Map。
List是一种常用的集合类型,它可以存储任意类型的对象,也可以结合泛型来存储具体的类型对象,本质上就是一个容器。

1.1 List 类型介绍

  1. 有序性: List中的元素是按照添加顺序进行存放的。因为有序,所以有下标,下标从0开始
  2. 可重复性: List中可以存储重复的元素
    List中主要有ArrayList、LinkedList两个实现类。
    在这里插入图片描述

2 List 接口

2.1 List 初始化

// 创建集合
List list = new ArrayList<>();

// 添加元素
list.add("hello");
list.add("world");
list.add("java");

// public boolean remove(Object o):删除指定的元素,返回删除是否成功
list.remove("world");//true
// public E remove(int index):删除指定索引处的元素,返回被删除的元素
list.remove(1);//world
// public E set(int index,E element):修改指定索引处的元素,返回被修改的元素
list.set(1,"javaee");//world

// IndexOutOfBoundsException
list.remove(3);

2.2 List 常用API

ArrayList和LinkedList通用方法。

方法名								说明
public boolean add(要添加的元素)		将指定的元素追加到此集合的末尾
public boolean remove(要删除的元素)	删除指定元素,返回值表示是否删除成功
public E remove(int index)			删除指定索引处的元素,返回被删除的元素
public E set(int index,E element)	修改指定索引处的元素,返回被修改的元素
public E get(int index)				返回指定索引处的元素
public int size()					返回集合中的元素的个数
boolean contains(Object o)			如果此列表包含指定的元素,则返回 true
boolean addAll(int index, Collection<? extends E> c)									
									将指定集合中的所有元素插入到此列表中,从指定的位置开始
void clear()						列表中删除所有元素

2.3 List 遍历方式

List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");

//方法一:超级for循环遍历
for(String attribute : list) {
  System.out.println(attribute);
}
//方法二:对于ArrayList来说速度比较快, 用for循环, 以size为条件遍历:
for(int i = 0 ; i < list.size() ; i++) {
  system.out.println(list.get(i));
}
//方法三:集合类的通用遍历方式, 从很早的版本就有, 用迭代器迭代
Iterator it = list.iterator();
while(it.hasNext()) {
  System.ou.println(it.next);
}

3 ArrayList

ArrayList是Java中的实现List接口的类,底层使用数组来存储元素。但与数组相比,它具有更灵活的大小和动态的增加和删除元素。

注意: 由于 ArrayList 底层使用的是数组,因此一旦创建了 ArrayList,它的大小就是固定的。而当元素添加到 ArrayList 中时,如果底层数组已满,则需要创建一个更大的数组,并将原有元素复制到新数组中,这会带来一定的性能损耗。
因此,在实际开发中,建议在创建 ArrayList 时设置一个合适的初始化容量,避免在运行时频繁进行扩容操作,同时也可避免浪费过多空间资源。
例如:new ArrayList(50);将ArrayList初始容量改为50

3.1 ArrayList 数据结构

ArrayList的数据结构本质上就是数组。区别在于,数组是一种静态的数据结构,需要在创建数组时就指定它的长度,并且创建后长度无法改变。而ArrayList是一种动态的数据结构,它可以自动进行扩容。

3.2 ArrayList 类定义

public class ArrayList<E> 
	extends AbstractList<E> 
	implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList是一个继承于AbstractList的线性数据结构。

AbstractList提供了List接口的默认实现(个别方法为抽象方法)

  • ArrayList 实现 List 接口,能对它进行队列操作。
  • ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
  • ArrayList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
  • ArrayList 实现RandomAccess接口,提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
    在这里插入图片描述

3.3 ArrayList 特点

除了具备List有序性、可重复性特点外,ArrayList还具备以下的特点:

  • 自动扩容 :当向ArrayList中加入的元素超过了其默认的长度时(由于ArrayList是数组的封装类,在创建ArrayList时不用给定长度,其默认长度为10),它会自动扩容以增加存储容量
  • 随机访问:随机访问是指可以直接访问元素,而不需要从头部或者尾部遍历整个列表。由于ArrayList底层是用数组实现的,因此可以通过索引来快速访问元素。
  • 慢速插入/删除::相比于链表(如LinkedList),ArrayList在中间插入或删除元素较慢,因为需要移动元素。
  • 高效的遍历:由于ArrayList底层采用了数组来存储元素,所以对于ArrayList的遍历操作比较高效。

3.4 ArrayList 特定API

方法名							说明
ArrayList() 					ArrayList构造函数。默认容量是10
ArrayList(int initialCapacity)  ArrayList带容量大小的构造函数
ArrayList(Collection<? extends E> c)
								创建一个包含collection的ArrayList
trimToSize()					将内部存储的数组大小调整为列表中元素的实际数量。
ensureCapacity(int minCapacity)	设置内部存储的数组大小,以容纳指定数量的元素。
toArray(T[] a)					将列表中的元素转换为指定类型的数组

4 LinkedList

LinkedList也是Java中实现List接口的常用集合类,底层使用的是双向链表数据结构。

与ArrayList不同,LinkedList在内部存储元素时,不是使用连续的内存空间,而是使用一个链表来存储元素。

4.1 LinkedList 数据结构

LinkedList底层采用的是双向链表(doubly linked list) 数据结构。链表中的每个节点(结点)都由两个部分组成,一部分是存储数据元素的值域,另一部分是指向前一个节点和后一个节点的指针(引用)。对于双向链表来说,除了一个指向前一个节点的指针外,还有一个指向后一个节点的指针
在这里插入图片描述

4.2 LinkedList 类定义

public class LinkedList<E>
     extends AbstractSequentialList<E>
     implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。

为什么要继承自AbstractSequentialList ?
AbstractSequentialList 实现了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)这些骨干函数。降低了List接口的复杂度。LinkedList双向链表通过继承于AbstractSequentialList,就相当于已经实现了“get(int index)这些接口”。
此外,若需要通过AbstractSequentialList自己实现一个自定义列表,只需要扩展此类,并提供 listIterator() 和 size() 方法的实现即可。若要实现不可修改的列表,则需要实现列表迭代器的 hasNext、next、hasPrevious、previous 和 index 方法即可。

  • LinkedList 实现 List 接口,能对它进行队列操作。
  • LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
  • LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
  • LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
    LinkedList 是非同步的。
    在这里插入图片描述

4.3 LinkedList 特点

  • 随机访问性能较差:LinkedList的随机访问性能较差,因为在链表中要从头开始遍历链表,直到找到目标元素。所以如果在代码中需要频繁进行随机访问元素的操作,LinkedList可能不是一个最佳的选择。
  • 添加/删除操作快:由于LinkedList底层使用双向链表,因此它的添加和删除操作非常快,因为只需要更改指针的指向即可,不需要像ArrayList一样重新分配数组空间,而且LinkedList还支持在指定位置插入和删除元素。
  • 需要额外空间:链表中每个节点都需要额外存储到前一个和后一个节点的指针,因此比数组等其他数据结构需要更多的内存空间。
  • 适用于队列和双端队列:LinkedList还可以支持队列和双端队列的功能,如在链表头部或尾部添加或删除元素,实现队列和双端队列的常见操作。

4.4 LinkList 特定API

方法名				说明
LinkedList()		构造方法
LinkedList(Collection<? extends E> c) 
					创建一个包含collection的LinkedList
addFirst(E element)	将元素添加到列表的开头
getFirst()  		返回列表的第一个元素。
getLast()			返回列表的最后一个元素。
removeFirst()		删除并返回列表的第一个元素。
removeLast()		删除并返回列表的最后一个元素。

5 ArrayList与LinkedList的比较

  • 由于ArrayList的数据结构为数组,所以查询修改快,新增删除慢;而LinkedList的数据结构为链表结构,所以查询修改慢,新增删除快
  • ArrayList是基于数组实现的动态数组,在内存中有连续的空间,可以通过下标访问元素,由于数组需要提前分配一定大小的空间,因此当元素数量增多之后,可能会导致数组空间不足需要重新分配数组,这种情况下可能会出现内存空间浪费;相比之下,LinkedList是基于链表实现的,每个元素都有一个引用指向下一个元素,不需要提前分配空间,因此能够更加灵活地插入和删除元素。然而,链表在内存中是不连续的,每个元素的引用占用额外的内存空间。由于链表中每个元素都需要有一个指向下一个元素的引用,因此在存储同样数量的元素时,LinkedList通常会占用比ArrayList更大的内存空间。

转载链接

https://www.cnblogs.com/lzq198754/p/5780165.html
https://blog.csdn.net/TestXzing/article/details/131197073
https://blog.csdn.net/jianyuerensheng/article/details/51204598

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Solr的全文检索系统的实现与应用

文章目录 一、概念1、什么是Solr2、与Lucene的比较区别1&#xff09;Lucene2&#xff09;Solr 二、Solr的安装与配置1、Solr的下载2、Solr的文件夹结构3、运行环境4、Solr整合tomcat1&#xff09;Solr Home与SolrCore2&#xff09;整合步骤 5、Solr管理后台1&#xff09;Dashbo…

Redis 五大经典业务问题

一 缓存穿透 缓存穿透是指当请求的数据既不在缓存中也不存在于数据库中时&#xff0c;请求会直接穿透缓存层&#xff0c;到达数据库层。这通常是由于恶意攻击或者程序错误造成的&#xff0c;比如攻击者故意请求不存在的大量数据&#xff0c;导致缓存不命中&#xff0c;所有的请…

python zblog API实现类似XMLRPC/发布文章

我发现python对Zblog的XML发布并不友好&#xff0c;虽然也有对应的模块&#xff0c;但是远远没有XPCRPC更直接方便&#xff0c;但是使用xmlRpc是直接给发布文章带来了不小的便利&#xff0c;但是对系统也并不友好&#xff0c;但是zblog也开放了Api&#xff0c;但是干部子弟不乐…

【Spring教程20】Spring框架实战:AOP(面对切面编程)知识总结

欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0c;如果您对Maven还很陌生&#xff0c;请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》&#xff0c;本文的上一篇为《利用 AOP通知获取数据代码…

为 Compose MultiPlatform 添加 C/C++ 支持(3):实战 Desktop、Android、iOS 调用同一个 C/C++ 代码

theme: serene-rose 前言 在本系列的前两篇文章中我们已经学会了如何在 kotlin native 平台&#xff08;iOS&#xff09;使用 cinterop 调用 C/C 代码。以及在 jvm 平台&#xff08;Android、Desktop&#xff09;使用 jni 调用 C/C 代码&#xff0c;并且知道了如何自动编译 A…

Leetcode—389.找不同【简单】

2023每日刷题&#xff08;五十五&#xff09; Leetcode—389.找不同 实现代码 char findTheDifference(char* s, char* t) {int len strlen(s);int len2 len 1;int a[26] {0};int b[26] {0};if(len 0) {return t[0];}for(int i 0; i < len; i) {int idx s[i] - a;…

使用alpine镜像部署go应用时踩的坑

使用alpine镜像部署go应用时踩的坑 关于交叉编译 实际上我在ubuntu的交叉编译出来的exe并不能在alpine上运行&#xff0c;这边采取拉镜像编译复制出来的做法&#xff0c;部署再用干净的alpine 拉取golang:alpine踩坑 在Dockerhub上可以找到&#xff1a; 然而拉取的alpine中…

蓝桥杯-动态规划专题-子数组系列,双指针

目录 一、单词拆分 二、环绕字符串中唯一的子字符串 双指针-三数之和 ArrayList(Arrays.asList(array)) 四、四数之和&#xff08;思路和三数之和一样&#xff0c;只是多了一层循环&#xff09; 一、单词拆分 1.状态表示 dp[i]:到达i位置结尾&#xff0c;能否被dict拆分 …

JVM进程缓存

引言 缓存在日常开发中启动至关重要的作用&#xff0c;由于是存储在内存中&#xff0c;数据的读取速度是非常快的&#xff0c;能大量减少对数据库的访问&#xff0c;减少数据库的压力。我们把缓存分为两类&#xff1a; 分布式缓存&#xff0c;例如Redis&#xff1a; 优点&…

【MySQL】MySQL 在 Centos 7环境安装教程

文章目录 1.卸载不要的环境2.检查系统安装包3.获取mysql官方yum源4.安装mysql yum 源&#xff0c;对比前后yum源5.安装mysql服务6.查看配置文件和数据存储位置7.启动服务和查看启动服务8.登录9.配置my.cnf 1.卸载不要的环境 先检查是否有mariadb存在 ps ajx |grep mariadb如果…

虚拟机VMware安装centos以及配置网络

目录 1、CentOS7的下载2、CentOS7的配置3、CentOS7的安装4、CentOS7的网络配置 4.1、自动获取IP4.2、固定获取IP 5、XShell连接CentO 准备工作&#xff1a;提前下载和安装好VMware。VMware的安装可以参考这一篇文章&#xff1a;VMware15的下载及安装教程。 1、CentOS7的下载 …

sentinel整合nacos配置中心持久化

在网上找了很多的资料&#xff0c;发现sentinel整合nacos持久化的博文和视频大多数都只有改造限流部分的教程&#xff0c;并且都需要修改前端&#xff0c;略显麻烦&#xff0c;至于剩下的熔断、热点流控、授权的更是没有相关的改造教程&#xff0c;最后在知乎的看到一篇文章后让…

Sql server数据库数据查询

请查询学生信息表的所有记录。 答&#xff1a;查询所需的代码如下&#xff1a; USE 学生管理数据库 GO SELECT * FROM 学生信息表 执行结果如下&#xff1a; 查询学生的学号、姓名和性别。 答&#xff1a;查询所需的代码如下&#xff1a; USE 学生管理数据库 GO SELE…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑移动式储能调度的配电网灾后多源协同孤岛运行策略》

这篇文章的标题表明研究的主题是在配电网发生灾害后&#xff0c;采用一种策略来实现多源协同孤岛运行&#xff0c;并在这个过程中特别考虑了移动式储能的调度。 让我们逐步解读标题的关键词&#xff1a; 考虑移动式储能调度&#xff1a; 文章关注的焦点之一是移动式储能系统的…

持续集成交付CICD:Jenkins流水线实现Nexus制品晋级策略

目录 一、理论 1.开发测试运维环境 二、实验 1.Nexus制品晋级策略 一、理论 1.开发测试运维环境 &#xff08;1&#xff09;环境 1&#xff09;持续集成开发环境&#xff08;DEV: Development Environment&#xff09; 直接通过源代码编译打包&#xff0c;其会跑单元测试…

Vue之数据绑定

在我们Vue当中有两种数据绑定的方法 1.单向绑定 2.双向绑定 让我为大家介绍一下吧&#xff01; 1、单向绑定(v-bind) 数据只能从data流向页面 举个例子&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

Docker Compose(容器编排)——9

目录 什么是 Docker Compose生活案例为什么要 Docker ComposeDocker Compose 的安装Docker Compose 的功能Docker Compose 使用场景Docker Compose 文件&#xff08;docker-compose.yml&#xff09; 文件语法版本文件基本结构及常见指令Docker Compose 命令清单 命令清单如下命…

Java项目-瑞吉外卖Day4

实现文件的上传下载&#xff1a; 前端代码&#xff1a; 对文件的操作就是对流的操作。 上传文件的后端代码&#xff0c;需要注意MultipartFile的名字必须与前端相对&#xff1a; 为文件存储位置进行动态设置&#xff0c;配置application.xml 在CommonController中设置属性读…

【Python网络爬虫入门教程2】成为“Spider Man”的第二课:观察目标网站、代码编写

Python 网络爬虫入门&#xff1a;Spider man的第二课 写在最前面观察目标网站代码编写 第二课总结 写在最前面 有位粉丝希望学习网络爬虫的实战技巧&#xff0c;想尝试搭建自己的爬虫环境&#xff0c;从网上抓取数据。 前面有写一篇博客分享&#xff0c;但是内容感觉太浅显了…

【Linux】使用Bash和GNU Parallel并行解压缩文件

介绍 在本教程中&#xff0c;我们将学习如何使用Bash脚本和GNU Parallel实现高效并行解压缩多个文件。这种方法在处理大量文件时可以显著加快提取过程。 先决条件 确保系统上已安装以下内容&#xff1a; BashGNU Parallel 你可以使用以下命令在不同Linux系统上安装它们&am…