Java集合框架——List接口的使用

2023-10-27

学习Java的同学注意了!!! 
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:183993990  我们一起学Java!


    List集合代表一个有序集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。

1、List接口和ListIterator接口

    List作为Collection接口的子接口,可以使用Collection接口里的全部方法。List是有序集合,所以List集合里增加了一些根据索引来操作集合元素的方法:

  • void add(int index, Object element):将元素element插入在List集合的index处。
  • boolean addAll(int index, Collection c):将集合c所包含的所有元素都插入在List集合的index处。
  • Object get(int index):返回集合index索引处的元素。
  • int lastIndexOf(Object o):返回对象o在List集合中最后一次出现的位置索引。
  • Object remove(int index):删除并返回index索引处的元素。
  • Object set(int index, Object element):将index索引处的元素替换成element对象,返回新元素。
  • List subList(int fromIndex, int toIndex):返回从索引fromIndex(包含)到索引toIndex(不包含)处所有集合元素组成的子集合。

    List集合可以根据索引来插入、替换和删除集合元素。

示例程序:

public class TestList { public static void main(String[] args) { List books = new ArrayList(); //向books集合中添加三个元素
        books.add(new String("轻量级J2EE企业应用实战")); books.add(new String("Struts2权威指南")); books.add(new String("基于J2EE的Ajax宝典")); System.out.println(books); //将新字符串对象插入在第二个位置
        books.add(1 , new String("ROR敏捷开发最佳实践")); //已添加的对象,和下面语句做对比
        for (int i = 0 ; i < books.size() ; i++ ) { System.out.println(books.get(i)); } //删除第三个元素
        books.remove(2); System.out.println(books); //判断指定元素在List集合中位置:输出1,表明位于第二位
        System.out.println(books.indexOf(new String("ROR敏捷开发最佳实践"))); //新创建的对象 //将第二个元素替换成新的字符串对象
        books.set(1, new String("Struts2权威指南")); System.out.println(books); //将books集合的第二个元素(包括)到第三个元素(不包括)截取称子集合
        System.out.println(books.subList(1 , 2)); } }

程序运行结果:

[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典] 
轻量级J2EE企业应用实战 
ROR敏捷开发最佳实践 
Struts2权威指南 
基于J2EE的Ajax宝典 
[轻量级J2EE企业应用实战, ROR敏捷开发最佳实践, 基于J2EE的Ajax宝典] 

[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典] 
[Struts2权威指南]

程序说明:List集合可以使用普通for循环来遍历集合元素。List判断两个对象相等只要通过equals方法比较返回true即可。如在判断“ROR敏捷开发最佳实践”字符串的位置是,新创建了一个新字符串对象,但是程序仍返回第一次创建字符串对象的位置。当调用List的set(int index, Object element)方法来改变List集合指定索引处元素时,指定的索引必须是List集合的有效索引。

     与set只提供了一个iterator()方法不同,List还额外提供了一个listIteratro()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iterator接口,提供了专门操作List的方法。

ListIterator接口在Iterator接口基础上增加了如下方法:

  • boolean hasPrevious():返回该迭代器关联集合是否还有上一个元素。
  • Object previous():返回该迭代器上一个元素。
  • void add():在指定位置插入一个元素。

程序示例:

public static void main(String[] args) { String[] books = { "Struts2权威指南", "轻量级J2EE企业应用实战" }; List bookList = new ArrayList(); for (int i = 0; i < books.length ; i++ ) { bookList.add(books[i]); } ListIterator lit = bookList.listIterator(); while (lit.hasNext()) { System.out.println(lit.next()); lit.add("-------分隔符-------"); } System.out.println("==========下面开始反向迭代==========="); while(lit.hasPrevious()) { System.out.println(lit.previous()); } } }

程序运行结果:

Struts2权威指南 
轻量级J2EE企业应用实战 
==========下面开始反向迭代=========== 
-------分隔符------- 
轻量级J2EE企业应用实战 
-------分隔符------- 
Struts2权威指南

程序说明:List通过ListTterator迭代集合时,即可采用next()方法进行正向迭代,迭代过程中可以使用add()方法向上一次迭代元素的后面添加一个新元素。同时程序演示了向前迭代。

 2、ArrayList和Vector实现类

    ArrayList和Vector作为List类的两个典型实现,完全支持前面介绍的List接口全部功能。

    ArrayList和Vector类都是基于数组实现的List类,他们封装了一个动态再分配的Object[]数组。每个ArrayList或Vector对象有一个capacity属性,表示它们所封装的Object[]数组的长度。capacity会添加元素的个数而自动增加。当向集合中添加大量元素时,可以使用ensureCapacity方法一次性地增加capacity。这可以减少增加重分配次数,从而提供性能。capacity大小也可以在创建时就指定,该属性默认为10.

ArrayList和Vector提供如下两个方法来操作capacity属性:

  • void ensureCapacity(int minCapacity):将ArrayList或Vector集合的capacity增加minCapacity。
  • void trimToSize():调整ArrayList或Vector集合的capacity为列表当前大小。程序可调用该方法来减少ArrayList或Vector集合对象存储空间。

    ArrayList和Vector用法几乎相同,Vector是一个古老的集合(从JDK1.0),起初Java还没有提供系统的集合框架,所以Vector里提供了一些方法名很长的方法:例如addElement(Object obj), 等同于add()方法。从JDK1.2以后,Java提供了系统的集合框架,就将Vector改为实习List接口,作为List的实习之一,从而导致Vector里有一些功能重复的方法。Vector具有很多缺点,通常尽量少用Vector实现类。

 

   ArrayList和Vector的区别:ArrayList是线程不安全的,多个线程访问同一个ArrayList集合时,如果有超过一条线程修改了ArrayList集合,则程序必须手动保证该集合的同步性。Vector集合则是线程安全的,无线程序保证该集合的同步性。因为Vector是线程安全的,所以Vector的性能比ArrayList的性能要低。实际上,即使保证List集合线程安全,同样不推荐使用Vector实现类。Collections工具类,可以将一个ArrayList变成线程安全的

 

   Vector还提供了一个Stack子类,它用于模拟了”栈“这种数据结构,”栈“通常是指”后进先出“(LIFO)的容器。最后”push“进栈的元素,将最先被”pop“出栈。与Java中其他集合一样,进栈出栈的都是Object,因此从栈中取出元素后必须做类型转换,除非你只是使用Object具有的操作。所以stack类提供了如下几个方法:

  • Object peek():返回”栈“的第一个元素,但并不将该元素”pop“出栈。
  • Object pop():返回”栈“的第一个元素,并将该元素”pop“出栈。
  • void push(Object item):将一个元素”push“进栈,最后一个进”栈“的元素总是位于”栈“顶。

程序示例:

public class TestVector { public static void main(String[] args) { Stack v = new Stack(); //依次将三个元素push入"栈"
        v.push("Struts2权威指南"); v.push("轻量级J2EE企业应用实战"); v.push("ROR敏捷开发最佳实践"); //输出:[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践]
 System.out.println(v); //访问第一个元素,但并不将其pop出"栈",输出:ROR敏捷开发最佳实践
 System.out.println(v.peek()); //依然输出:[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践]
 System.out.println(v); //pop出第一个元素,输出:ROR敏捷开发最佳实践
 System.out.println(v.pop()); //依然输出:[Struts2权威指南, 轻量级J2EE企业应用实战]
 System.out.println(v); } }

程序运行结果:

[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践] 
ROR敏捷开发最佳实践 
[Struts2权威指南, 轻量级J2EE企业应用实战, ROR敏捷开发最佳实践] 
ROR敏捷开发最佳实践 
[Struts2权威指南, 轻量级J2EE企业应用实战]

   3、LinkedList实现类

    List还有一个LinkedList的实现,它是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化,特别是当插入、删除元素时速度非常快。因为LinkedList即实现了List接口,也实现了Deque接口(双向队列),Deque接口是Queue接口的子接口,它代表一个双向列表,Deque接口里定义了一些可以双向操作队列的方法:

  • void addFirst(Object e):将制定元素插入该双向队列的开头。
  • void addLast(Object e):将制定元素插入该双向队列的末尾。
  • Iterator descendingIterator():返回以该双向队列对应的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。
  • Object getFirst():获取、但不删除双向队列的第一个元素。
  • Object getLast(): 获取、但不删除双向队列的最后一个元素。
  • boolean offerFirst(Object e): 将指定的元素插入该双向队列的开头。
  • boolean offerLast(Object e): 将指定的元素插入该双向队列的末尾。
  • Object peekFirst(): 获取、但不删除该双向队列的第一个元素:如果此双端队列为空,则返回null。
  • Object peekLast():获取、但不删除该双向队列的最后一个元素:如果此双端队列为空,则返回null。
  • Object pollFirst():获取、并删除该双向队列的第一个元素:如果此双端队列为空,则返回null。
  • Object pollLast():获取、并删除该双向队列的最后一个元素:如果此双端队列为空,则返回null。
  • Object pop():pop出该双向队列所表示的栈中第一个元素。
  • void push(Object e):将一个元素push进该双向队列所表示的栈中(即该双向队列的头部)。
  • Object removerFirst():获取、并删除该双向队列的最后一个元素。
  • Object removeFirstOccurrence(Object o):删除该双向队列的第一次的出现元素o。
  • Object removeLast():获取、并删除该双向队列的最后一个元素。
  • Object removeLastOccurrence(Object o):删除该双向队列的最后一次出现的元素o。

从上面方法中可以看出,LinkedList不仅可以当成双向队列使用,也可以当成“栈”使用。同时,LinkedList实现了List接口,所以还被当成List使用。

程序示例:

public class TestLinkedList { public static void main(String[] args) { LinkedList books = new LinkedList(); //将字符串元素加入队列的尾部
        books.offer("Struts2权威指南"); //将一个字符串元素入栈
        books.push("轻量级J2EE企业应用实战"); //将字符串元素添加到队列的头部
        books.offerFirst("ROR敏捷开发最佳实践"); for (int i = 0; i < books.size() ; i++ ) { System.out.println(books.get(i)); } //访问、并不删除队列的第一个元素
 System.out.println(books.peekFirst()); //访问、并不删除队列的最后一个元素
 System.out.println(books.peekLast()); //采用出栈的方式将第一个元素pop出队列
 System.out.println(books.pop()); //下面输出将看到队列中第一个元素被删除
 System.out.println(books); //访问、并删除队列的最后一个元素
 System.out.println(books.pollLast()); //下面输出将看到队列中只剩下中间一个元素:轻量级J2EE企业应用实战
 System.out.println(books); } }

程序运行结果:

ROR敏捷开发最佳实践 
轻量级J2EE企业应用实战 
Struts2权威指南 
ROR敏捷开发最佳实践 
Struts2权威指南 
ROR敏捷开发最佳实践 
[轻量级J2EE企业应用实战, Struts2权威指南] 
Struts2权威指南 
[轻量级J2EE企业应用实战]

说明:程序中示范了LinkedList作为双向队列、栈和List集合的用法。LinkedList与ArrayList、Vector的实现机制完全不同,ArrayList、Vector内部以数组的形式来保存集合中的元素,因此随机访问集合元素上有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合时性能较差,但在插入、删除元素时性能非常出色(只需改变指针所指的地址即可)。Vector因实现了线程同步功能,所以各方面性能有所下降。

 

关于使用List集合的几点建议:

  • 如果需要遍历List集合元素,对应ArrayList、Vector集合,则应该使用随机访问方法(get)来遍历集合元素,这样性能更好。对应LinkedList集合,则应采用迭代器(Iterator)来遍历集合元素。
  • 如果需要经常执行插入、删除操作来改变Lst集合大小,则应该使用LinkedList集合,而不是ArrayList。
  • 如果多条线程需要同时访问List集合中的元素,可以考虑使用Vector这个同步实现。

学习Java的同学注意了!!! 
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:183993990  我们一起学Java!

转载于:https://my.oschina.net/abcijkxyz/blog/851089

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java集合框架——List接口的使用 的相关文章

  • Android:java.lang.OutOfMemoryError:

    我在 Android 上开发了一个使用大量图像的应用程序 可绘制文件夹中有很多图像 比如说超过 100 张 我正在开发图像动画应用程序 我使用 imageview 来显示 GIF 图像 我使用了将 gif 图像分割成多个 PNG 格式图像的
  • 将处理项目移至 Eclipse

    我已经在处理项目上工作了一段时间 现在想将其移至 Eclipse 中 我已经在 Eclipse 环境中安装了 Proclipse 我有很多扩展名为 pde 的文件 然而 Proclipse 文件都以 java 结尾 所有 pde 文件都存在
  • Java,顺序流在哪个线程中执行?

    在阅读有关流的文档时 我遇到了以下句子 attempting to access mutable state from behavioral parameters presents you with a bad choice if you
  • Hashset - 创建 Set 后使对象相同

    如果我们在 HashSet 中添加两个不同的对象 可变的 然后通过调用 setter 更改对象的值 使它们相同 则大小仍然是 hashSet 的 2 我无法理解其原因 public static void main String args
  • java 中的梵文 i18n

    我正在尝试使用来自互联网的示例 ttf 文件在 java 中使用 i18n 进行梵文 印地文 我可以加载资源包条目 还可以加载 ttf 并设置字体 但它不会根据需要呈现 jlabel 它显示块代替字符 如果我在 Eclipse 中调试 我可
  • 垂直 ViewPager 中的动画

    我需要垂直制作这个动画ViewPager https www youtube com watch v wuE 4jjnp3g https www youtube com watch v wuE 4jjnp3g 这是我到目前为止所尝试的 vi
  • Java Junit 测试 HTTP POST 请求

    我需要测试以下方法而不改变方法本身 该方法向服务器发出 POST 方法 但我需要制作一个独立于服务器的测试用例 在将其重定向到本地文件之前 我测试了类似的方法 但为此我将协议指定为文件 主机名指定为 localhost 端口指定为 1 我的
  • 绘制平滑曲线

    我想创建更平滑的曲线 而不仅仅是线角 这是我现在画的图 这是我的代码 case FREEHAND float pts float ptk ptk new float 2 imageMatrix invert inv if mCurrentS
  • Java 中如何验证字符串的格式是否正确

    我目前正在用 Java 编写一个验证方法来检查字符串是否是要更改为日期的几种不同格式之一 我希望它接受的格式如下 MM DD YY M DD YY MM D YY 和 M D YY 我正在测试第一种格式 每次它都告诉我它无效 即使我输入了有
  • 如何在 Eclipse 中获得完全限定的类名?

    有没有一种快速方法可以在 Eclipse 中单击 Java 类并获取其完全限定名称 或将其复制到剪贴板 2016年6月29日编辑 正如 Jeff 所指出的 您只需要执行以下第二步 1 Double click on the class na
  • 如何让“循环”泛型在 Java 中工作?

    我在编译以下涉及一些泛型的代码时遇到错误 public abstract class State
  • 在Java中如何将字节数组转换为十六进制?

    我有一个字节数组 我希望该数组的每个字节字符串转换为其相应的十六进制值 Java中有没有将字节数组转换为十六进制的函数 byte bytes 1 0 1 2 3 StringBuilder sb new StringBuilder for
  • 错误膨胀类 android.support.design.widget.NavigationView [启动时崩溃]

    该应用程序应该有一个导航抽屉 可以从左侧拉出并显示各种活动 但是一旦将导航栏添加到 XML Activity homescreen 文档中 应用程序一启动就会崩溃 主屏幕 java package com t99sdevelopment c
  • 如何使用 Java 在 selenium webdriver 中打开新选项卡或如何使用使用 selenium webdriver 的操作类在 selenium 中按 ctrl +T [重复]

    这个问题在这里已经有答案了 如何使用 Java 在 Selenium Webdriver 中按 CTRL T 或者 如何使用 Java 在 selenium webdriver 中打开新选项卡 简单步骤 1 打开google com 不必触
  • 接口是否像对象一样对待?

    为什么下面的代码可以工作 interface I class A implements I public String toString return in a class B extends A public String toStrin
  • Janusgraph 0.3.2 + HBase 1.4.9 - 无法设置 graph.timestamps

    我在 Docker 容器中运行 Janusgraph 0 3 2 并尝试使用运行 HBase 1 4 9 的 AWS EMR 集群作为存储后端 我可以运行 gremlin server sh 但如果我尝试保存某些内容 我会得到粘贴在下面的堆
  • 从字节数组设置 img src

    我需要设置img src我在对象中拥有的字节数组的属性 img
  • 如何使用eclipse调试JSP tomcat服务?

    我想使用 Eclipse IDE 调试器来调试单独运行的 JSP Struts Tomcat Hibernate 应用程序堆栈 如何设置 java JVM 和 eclipse 以便设置断点 监视变量值并查看当前正在执行的代码 我刚刚用谷歌搜
  • 使用 Java 8 Spring 4 + MyBatis 集成问题

    使用 Java 8 1 8 0 60 Spring 4 2 1 和 MyBatis 3 3 0 时遇到以下异常 Sep 29 2015 11 02 58 AM org springframework context annotation A
  • Android ClassNotFoundException:在路径上找不到类

    10 22 15 29 40 897 E AndroidRuntime 2561 FATAL EXCEPTION main 10 22 15 29 40 897 E AndroidRuntime 2561 java lang Runtime

随机推荐

  • docker容器连接宿主机redis和mysql

    当我们在用docker部署项目的时候可能会遇到这样一个问题 项目A和项目B都用到了redis和mysql 如果在docker compose里link或者dependon一个redis和mysql的话 会发现每一个项目都有一个redis和m
  • static作用:静态变量的生存周期和作用域

    首先要理解生存周期与作用域的区别 生存周期 变量从定义到销毁的时间范围 存放在全局数据区的变量的生存周期存在于整个程序运行期间 而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁 除了静态变量之外的局部变量都存放于栈中 作用域 变量的
  • 多路开关模式的switch语句

    在实例10中 将break语句去掉之后 会将符合检验条件后的所有语句都输出 利用这个特点 可以设计多路开关模式的switch语句 例如 在平年一年12个月 1 3 5 7 8 10 12月是31天 4 6 9 11月是30天 2月是28天
  • 第1144期AI100_机器学习日报(2017-11-05)

    AI100 机器学习日报 2017 11 05 聊天机器人Chatbot知识资料全集 入门 进阶 论文 软件 数据 专家等 wx 专知内容组 推荐中的序列化建模 Session based neural recommendation wx
  • Echarts饼状legend如何自动显示值和百分比

    效果图如下 重点在legend里如何设置 显示值和百分比 div class div block strong class block box title 硬盘使用情况 总容量 total strong div div div
  • 如何写出好的接口测试用例?一文1500字从0到1教你写一个合格的接口测试用例

    作为测试人 我们经常要对项目中的接口进行接口测试 那么在做接口测试的时候 如何写接口测试用例呢 如何写出好的接口测试用例呢 什么是接口测试 首先我们要了解一下 什么是接口测试 那么首先要搞清楚 我们一般说的接口到底是什么 一般狭义上说的都是
  • Linux查看二进制文件

    方法一 使用hexedit 下载 sudo apt get install hexedit 然后使用hexedit命令就行了 方法二 使用vim 先用vim b file打开文件 然后输入 xxd命令转换为十六进制 输入 xxd r返回原显
  • IntelliJ IDEA:删除当前一整行

    参考 https blog csdn net weixin 40836179 article details 81360342
  • 从 Spec.到芯片_(数字IC、模拟IC、FPGA/CPLD设计的流程及EDA工具)

    从 Spec 到芯片 先来看张图 本图体现出了集成电路产业链 设计业 制造业 封测业 关于制造 封装测试我们看两张图稍作了解即可 关于设计 是本文主要内容 主要从下方几个方面了解 1 IC设计大致分类 2 IC设计需要考虑的因素 3 数字I
  • 01LinuxC线程学习之线程概念,简述与进程区别和查看LWP轻量级线程号(不是PID也不是TID))

    1 线程 1 1 线程概念 1 线程概念 每个线程有各自的PCB 但没有独立的地址空间 共享 注 该地址空间指的是以进程为单位 不是指栈 而进程拥有独立地址空间 拥有PCB 2 LWP light weight process 轻量级的进程
  • 【华为OD机试真题2023B卷 JAVA&JS】IPv4地址转换成整数

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 IPv4地址转换成整数 时间限制 1秒 内存限制 262144K 语言限制 不限 题目描述 存在一种虚拟IPv4地址 由4小节组成 每节的范围为0 255 以 号间隔 虚拟IPv4地址
  • Midjourney如何集成到自己(个人/企业)的平台(一)

    背景概述 目前Midjourney没有对外开放Api 想体验他们的服务只能在discord中进入他们的频道进行体验或者把他们的机器人拉入自己创建的服务器中 目前免费的已经无法体验了 需要使用就订阅 在网上搜索相应资料也是一知半解的 没有能照
  • tomcat 线程池和连接池

    在介绍如何配置tomcat线程池和连接池之前 先介绍一下线程池和连接池的原理 线程池的原理 其实线程池的原理很简单 类似于操作系统中的缓冲区的概念 它的流程如下 先启动若干数量的线程 并让这些线程都处于睡眠状态 当客户端有一个新请求时 就会
  • C# WPF并行计算两个矩阵

    并行计算两个矩阵 要求 编写一个WPF应用程序 利用数据并行计算两个矩阵 M N和N P 的乘积 得到一个M P的矩阵 1 在代码中用多任务通过调用某方法实现矩阵并行运算 在调用的参数中分别传递M N P的大小 2 程序中至少要测试3次有代
  • php7.3 "continue" targeting switch is equivalent to "break"

    php 7 3 版本导入Excel时报错 continue targeting switch is equivalent to break Did you mean to use continue 2 解决办法找到报错位置 将continu
  • interface{}类型通过json.Unmarshal之后的类型

    一句话总结 所有JSON数值类型一律解析为float64类型 需手动转换 对于map类型需判断是否为nil再转换为所需类型 interface 类型在json Unmarshal时 会自动将JSON转换为对应的数据类型 JSON的boole
  • 三星打印机显示无法连接服务器,三星打印机不能打印,提示“无法识别的USB设备”解决办法...

    打印机安装在电脑中之后出现无法识别的USB设备问题了 对于这个问题我们从几个方向来给各位排查无法识别的USB设备问题的解决办法 如图1 无法识别的USB设备 如图2 如果您USB设备没有被电脑识别 如下图所示 在电脑设备管理器里面会出现一个
  • OTA: Optimal Transport Assignment for Object Detection 原理与代码解读

    paper OTA Optimal Transport Assignment for Object Detection code https github com Megvii BaseDetection OTA 背景 标签分配 Label
  • SpringCloud @FeignClient 参数详解

    SpringCloud FeignClient 参数详解 今天因为工作中遇到FeignClient一个奇葩的bug 后面仔细研究了 找出了原因 那么刚好对FeignClient 这个注解总结一下 1 先看 FeignClient 源码 源码
  • Java集合框架——List接口的使用

    学习Java的同学注意了 学习过程中遇到什么问题或者想获取学习资源的话 欢迎加入Java学习交流群 群号码 183993990 我们一起学Java List集合代表一个有序集合 集合中每个元素都有其对应的顺序索引 List集合允许使用重复元