List集合以及它的实现类和队列、栈

news2024/7/6 18:01:30

List集合

Collection层次的结构接口中,一些允许有重复的元素,例如:List接口。而另外一些不允许有重复的元素,例如:Set接口。其中也分为了有序与无序的(存储顺序)。

在JDK中没有提供Collection接口的实现类,但是提供了更加具体的子接口(如Set、List和Queue接口)。

现在我们具体看一下List接口的特点。

Collection思维导图

List接口的介绍

List接口是位于java.util包下的一个Collection子接口,是单列集合的一种,通常情况下我们会将所有实现了List接口的对象都称为List接口

List接口的特点:

  • List接口中的元素存取是有序的,按照线性方式进行存储。例如:按照 a、b、c进入,也按照a、b、c取出。
  • List集合是带有索引的集合,通过索引可以更精确的操作集合中的元素(与数组的索引类似)
  • List集合中的元素可以重复

LIst接口中的常用方法

List接口是Collection集合中的子接口,不仅继承了Collection集合中的全部方法,而且还增加了一些根据元素索引操作集合的特有方法。

Collection集合中的方法详见:Collection集合以及方法

List集合中的特有方法

1、添加元素

  • void add(int index,E ele):在指定索引位置添加元素ele
  • boolean addAll(int index,Collection<? extends E> eles):在指定位置添加一个集合eles中的所有元素(<? extends E>表示泛型上限)

2、获取元素

  • E get(int index):获取List集合中指定索引位置的元素
  • List subList(int fromIndex,int toIndex):获取List集合中指定片段[fromIndex,toIndex)的索引

3、获取元素索引

  • int indexOf(Object obj):获取指定元素的第一个索引
  • int lastIndexOf(Object obj):获取指定元素的最后一个索引

4、删除元素

  • E remove(int index):删除指定索引位置的元素,返回的是删除的元素的值

5、替换元素

  • E set(int index,E ele):将指定索引位置的元素替换为新的元素ele

代码测试:

public class ListMethod {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(123);
        list.add("abc");
        System.out.println("list = " + list); //list = [123, abc]

        list.add(1,"java");
        System.out.println("list = " + list); //list = [123, java, abc]

        List l = new ArrayList();
        l.add("list");
        l.add("set");
        list.addAll(2,l);
        System.out.println("list = " + list); //list = [123, java, list, set, abc]

        Object o = list.get(1);
        System.out.println("o = " + o); //o = java

        List subList = list.subList(1, 4);
        System.out.println("subList = " + subList); //subList = [java, list, set]

        int javaIndex = list.indexOf("java");
        System.out.println("javaIndex = " + javaIndex); //javaIndex = 1

        list.add("java");
        int javaLastIndex = list.lastIndexOf("java");
        System.out.println("javaLastIndex = " + javaLastIndex); //javaLastIndex = 5

        Object remove = list.remove(4);
        System.out.println("remove = " + remove); //remove = abc
        System.out.println("list = " + list); //list = [123, java, list, set, java]

        list.set(4,"spring");
        System.out.println("list = " + list); //list = [123, java, list, set, spring]
    }
}

结果演示:
List特有方法的结果演示

List集合的遍历方法

List集合中除了Collection集合中的Iterator迭代器增强for循环两种遍历方式外还增加了另外两种迭代器方式:普通for循环ListIterator迭代器

  • Iterator迭代器
public class GetEleTest {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("iterator");
        list.add("foreach");
        list.add("for");
        list.add("ListIterator");

        Iterator iterator = list.iterator();
        while (iterator.hasNext()){ //iterator foreach for ListIterator 
            String element = (String) iterator.next();
            System.out.print(element+" "); 
        }
    }
}

Iterator迭代器测试

  • 增强for
public class GetEleTest {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("iterator");
        list.add("foreach");
        list.add("for");
        list.add("ListIterator");

        for (Object element : list){ //iterator foreach for ListIterator 
            String string = (String) element;
            System.out.print(string + " ");
        }
    }
}

增强for测试

  • 普通的for循环

因为List集合中提供了根据索引操作元素的方法,所以可以通过使用get(index)方法来进行获取元素值并遍历

public class GetEleTest {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("iterator");
        list.add("foreach");
        list.add("for");
        list.add("ListIterator");

        for (int i = 0; i < list.size(); i++) { //iterator foreach for ListIterator 
            System.out.print(list.get(i)+" ");
        }
    }
}

普通for循环遍历

  • ListIterator迭代器
    除了上面三种的遍历方式,LIst集合还提供了一种专门用于遍历LIst集合的方式:listIterator(),该方法返回了一个列表的迭代器对象,ListIterator是一个接口,该接口继承了Iterator接口,里面封装了一些特有的方法。

  • void add():铜鼓迭代器添加元素到对应的集合

  • void set(Object obj):通过迭代器替换正在迭代的元素

  • void remove():通过迭代器删除刚迭代的元素

  • boolean hasNext():判断是否有下一个元素

  • boolean hasPrevious():往前遍历,判断是否有前一个元素

  • Object next():获取下一个元素

  • Object previous():获取前一个的元素

  • int nextIndex():向后遍历,返回元素的索引

  • int previousIndex():向前遍历,返回元素的索引

public class GetEleTest {
    public static void main(String[] args) {

        List list = new ArrayList();
        list.add("iterator");
        list.add("foreach");
        list.add("for");
        list.add("ListIterator");

        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext()){
            System.out.print(listIterator.nextIndex());
            String next = (String) listIterator.next();
            System.out.print(":"+next+" ");
        }
        System.out.println();
        while (listIterator.hasPrevious()){
            System.out.print(listIterator.previousIndex());
            Object previous = listIterator.previous();
            System.out.print(":" +previous+" ");
        }
    }
}

listIterator迭代器测试

List接口的实现类

ArrayList集合

ArrayList集合List接口的典型实现类,底层使用的是长度可变的数组,ArrayList集合中的元素可以为空。

因为ArrayList集合的底层使用的动态数组进行存储数据,所以ArrayList集合的查询元素效率较快,但是增、删较慢。

ArrayList集合的底层实现:
ArrayList底层实现

ArrayList没有自己特殊的方法,常用的方法都是来自于Collection集合和List集合

Collection集合中的方法详见:Collection集合以及方法

ArrayList集合与Vector集合进行比较,两者都是使用的动态数组,但是ArrayList集合线程不安全,效率相对较高,Vector集合线程安全,基本上里面的每一个方法都有synchronized,所以效率相对较低。

ArrayList和Vector底层分析:

ArrayList底层实现:可变长的数组,有索引,查询效率高,增删效率低
    构造方法:
            new ArrayList():
                    jdk6中,空参构造直接创建10长度的数组。
                    jdk7(新版)、jdk8中,默认初始容量0,在添加第一元素时初始化容量为10
             new ArrayList(int initialCapacity):
                    指定初始化容量
    添加元素:add(E e);
    	首次添加元素,初始化容量为10
        每次添加修改modCount属性值
        每次添加检查容量是否足够,容量不足时需要扩容,扩容大小为原容量的1.5倍
        如果添加的元素容量大于原容量的0.5倍,则直接以添加元素的容量作为扩容的容量大小
    移除元素:remove(E e);
        每次成功移除元素,修改modCount值
        每次成功移除需要需要移动元素,以保证所以元素是连续存储的(删除操作效率低的原因)
------------------------------
Vector实现类的不点:
	初始容量为10,容量不足时扩容,如果capacityIncrement为0 扩容增加为原来的2倍,否则容量为旧的长度+capacityIncrement。

LinkedList实现类

LinkedList类是另一个List接口的常用实现类

因为LinkedList集合的底层使用的双向链表结构,所以LinkedList集合的特点是增删快,但是查询慢。

LinkedLIst集合的底层结构:
LinkedList集合的地城结构
LinkedList集合的底层源码实现

LinkedList底层源码实现
LinkedList集合特有的操作首尾元素的方法:
首尾元素的操作效率高

  • void addFirst(Object obj):在链表的首节点添加一个元素
  • void addLast(Object obj):在链表的添加元素
  • Object getFirst():获取链表首节点的元素
  • Object getLast():获取链表尾结点的元素
  • Object removeFirst():移除链表首节点的元素
  • Object removeLast():移除链表尾结点的元素
public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList<Object> linkedList = new LinkedList<>();
        linkedList.add("linkedList");
        System.out.println("linkedList = " + linkedList); //[linkedList]
        linkedList.addFirst("ArrayList");
        System.out.println("linkedList = " + linkedList); //[ArrayList, linkedList]
        linkedList.addLast("Vector");
        System.out.println("linkedList = " + linkedList); //[ArrayList, linkedList, Vector]

        Object o = linkedList.get(1);
        System.out.println("o = " + o); //linkedList
        Object first = linkedList.getFirst();
        System.out.println("first = " + first); //ArrayList
        Object last = linkedList.getLast();
        System.out.println("last = " + last); //Vector

        Object remove = linkedList.remove(1);
        System.out.println("remove = " + remove); //linkedList
        System.out.println("linkedList = " + linkedList); //[ArrayList, Vector]
        Object removeFirst = linkedList.removeFirst();
        System.out.println("removeFirst = " + removeFirst); //ArrayList
        System.out.println("linkedList = " + linkedList); //[Vector]
        Object removeLast = linkedList.removeLast();
        System.out.println("removeLast = " + removeLast); //Vector
        System.out.println("linkedList = " + linkedList); //[]
    }
}

LinkedList特有方法演示

队列与栈

队列和栈都属于逻辑结构的一种,属于特殊的线性结构,其物理结构可以是数组,也可以是链表。

LinkedList也实现了Deque接口(双端队列),Deque接口提供了实现队列和栈结构的方法。

Stack是Vector的子类,Stack也是实现了栈结构,它是数组实现的栈结构

队列

队列(Queue)是一种(并非一定)先进先出(FIFO)的结构

方法名addremoveelementofferpollpeekputtake
作用增加一个元索移除并返回队列头部的元素返回队列头部的元素添加一个元素并返回true移除并返问队列头部的元素返回队列头部的元素添加一个元素移除并返回队列头部的元素
是否有异常队列已满,则抛出一个IIIegaISlabEepeplian异常队列为空,则抛出一个NoSuchElementException异常队列为空,则抛出一个NoSuchElementException异常队列已满,则返回false队列为空,则返回null队列为空,则返回null如果队列满,则阻塞队列为空,则阻塞
public class QueueAndDequeTest {
    public static void main(String[] args) {
        //LinkedList实现了Deque,Deque又继承了Queue
        Queue queue = new LinkedList();
        queue.add("queue");
        System.out.println("queue = " + queue); //[queue]
        Object element = queue.element();
        System.out.println("element = " + element); //queue
        Object remove = queue.remove();
        System.out.println("remove = " + remove); //queue
        System.out.println("queue = " + queue); //[]

        boolean dequeBoolean = queue.offer("deque");
        System.out.println("dequeBoolean = " + dequeBoolean); //true
        System.out.println("queue = " + queue); //[deque]
        Object peek = queue.peek();
        System.out.println("peek = " + peek); //deque
        System.out.println("queue = " + queue); //[deque]
        Object poll = queue.poll();
        System.out.println("poll = " + poll); //deque
        System.out.println("queue = " + queue); //[]
    }
}

Queue代码演示结果

是一种先进后出(FILO)或后进后进先出(LIFO)的结构。
Deque,名称 deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。此接口定义在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(nullfalse,具体取决于操作)。

双端队列也可用作 LIFO(后进先出)堆栈。应优先使用此接口而不是遗留 Stack 类。在将双端队列用作堆栈时,元素被推入双端队列的开头并从双端队列开头弹出。堆栈方法完全等效于 Deque 方法,如下表所示:

堆栈方法等效 Deque 方法
查看栈顶元素push(e)addFirst(e)
弹出栈pop()removeFirst()
压入栈peek()peekFirst()
    @Test
    public void test02(){
        //模拟栈操作
        LinkedList<String> stack = new LinkedList<>();

        //入栈
        stack.push("张三");
        stack.push("李四");
        stack.push("王五");
        stack.push("赵六");

        //删除栈顶元素 弹栈
        stack.pop();
        stack.pop();

        //获取栈顶元素
        Object peek = stack.peek();
        System.out.println("peek = " + peek);
    }

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

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

相关文章

ppt文件太大怎么变小,这6种方式很简单

ppt文件太大怎么变小&#xff1f; ppt文件通常用于公司会议、教育授课和商务演讲等场合&#xff0c;由于需要实现各种文档效果并插入大量图片&#xff0c;因此文件大小要远大于普通文档文件&#xff0c;占用的存储空间也不少。如果电脑中存储了大量PPT文件&#xff0c;并且不方…

不服不行!盘点那些编程界的天才少年,11岁参加国际比赛,靠奖金赚了40万美金

程序员是一项专业性极强的工作&#xff0c;需要很强的思维能力和动手能力&#xff0c;所以大多数程序员要比普通人更聪明&#xff0c;与其他职业相比&#xff0c;程序员应该是最爱学习的一行了。科技网络的发展太快&#xff0c;新的技术层出不穷&#xff0c;时刻都要更新自己的…

L2-041 插松枝 判断量少(PTA 天梯赛)

人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送器&#xff0c;每次推送一…

计算机组成原理第二章——数据的表示与运算(下)

提示&#xff1a;时光清浅处 一步一安然 文章目录前言2.3.1 浮点数的表示2.3.2 IEEE7542.2.3 浮点数的运算前言 本节主要讲三个问题&#xff0c;浮点数的表示&#xff0c;IEEE 754标准&#xff0c;浮点数的加减运算 2.3.1 浮点数的表示 浮点数的作用和基本原理 定点数可表示…

由浅入深了解HashMap源码

由经典面试题引入&#xff0c;讲解一下HashMap的底层数据结构&#xff1f;这个面试题你当然可以只答&#xff0c;HashMap底层的数据结构是由&#xff08;数组链表红黑树&#xff09;实现的&#xff0c;但是显然面试官不太满意这个答案&#xff0c;毕竟这里有一个坑需要你去填&a…

Java容器使用注意点

前置&#xff1a;问题 判空集合转map集合遍历集合去重集合转数组数组转集合 一&#xff1a;集合判空 《阿里巴巴 Java 开发手册》的描述如下&#xff1a; 判断所有集合内部的元素是否为空&#xff0c;使用 isEmpty() 方法&#xff0c;而不是 size()0 的方式。 我们在开发中也…

AI大模型突围战

最近&#xff0c;GPT赛道上争议不断&#xff0c;先是GPT-4的问世&#xff0c;用一些亮眼的功能让人类感叹自己是不是要丢工作&#xff1f;紧接着又有一封联名信刷屏&#xff0c;图灵奖得主、AI三巨头之一的约书亚本吉奥、埃隆马斯克等123个业界大佬&#xff0c;呼吁所有人工智能…

Vcpkg安装指定版本包或自定义安装包

文章目录前言寻找版本安装后话前言 windows一直用着vcpkg作为C跨平台开发的包管理&#xff0c;有些依赖要指定版本库&#xff0c;vcpkg目前最新的openssl版本是3.1.0&#xff0c;我想安装其他版本为例&#xff0c;开始本教程 寻找版本 以openssl举例&#xff0c;在vcpkg目录中…

react3:受控组件(表单默认变成受控)-组件通信 - typescript项目

受控组件&#xff1a;表单 非受控组件表单元素值不受所在组件状态的控制, 我们将这样的表单元素称作: 非受控组件. 受控组件受控组件 : 值受到 React 组件状态控制的表单元素一般是通过 defaultValue 属性, onChange 事件配合将非受控组件变为受控组件. 多表单元素操作 &#…

如果当前node.js版本和项目需要版本不一样,卸载重装其他版本node.js的方法

其实这种node.js版本不一样的问题&#xff0c;可以选择用nvm来管理node.js的不同版本。 此处仅总结卸载当前版本node.js重新安装所需版本node.js的方法 另&#xff1a;现在 用Vite官网里面的 yarn/npm等 的方法&#xff0c;创建Vue3项目——需要12版本的node.js 以下以本人 …

Vue3中readonly 与 shallowReadonly的使用区别?

文章目录前言readonly强行修改readonly&#xff1a;shallowReadonlyshallowReadonly强行修改结果&#xff1a;前言 readonly: 让一个响应式数据变为只读的&#xff08;深只读&#xff09;。 shallowReadonly&#xff1a; 让一个响应式数据变为只读的&#xff08;浅只读&#x…

真正好用的工业品ERP系统应该是什么样的?

一个好用的进销存ERP系统应该有以下特点&#xff1a; 1. 全面覆盖企业经营流程&#xff0c;包括采购、销售、库存、财务等模块&#xff0c;能够实现全方位的管理和控制。 2. 自定义配置&#xff0c;灵活地适应大多数用户的需求。 3. 数据精准、实时化&#xff0c;支持统计分…

基于CALMET诊断模型的高时空分辨率精细化风场模拟技术应用

【查看原文】气象数据相关分析及使用系列&#xff1a;基于CALMET诊断模型的高时空分辨率精细化风场模拟技术应用 在研究流场时&#xff0c;常用观测、模型风洞测试和数值模拟方法进行研究。但时常遇到研究区气象站点分布稀疏&#xff0c;不能代表周边复杂地形的风场。风洞模拟…

day7 线程的取消和清理

线程的取消 意义&#xff1a;随时杀掉一个线程 int pthread_cancel(pthread_t thread); 注意&#xff1a;线程的取消要有取消点才可以&#xff0c;不是说取消就取消&#xff0c;线程的取消点主要是阻塞的系统调用 如果没有取消点&#xff0c;手动设置一个&#xff1b; voi…

【网络应用开发】实验4——会话管理

目录 会话管理预习报告 一、实验目的 二、实验原理 三、实验预习内容 1. 什么是会话&#xff0c;一个会话的生产周期从什么时候&#xff0c;到什么时候结束&#xff1f; 2. 服务器是如何识别管理属于某一个特定客户的会话的&#xff1f; 3. 什么是Cookie&#xff0c;它的…

全网最详细,Python接口自动化测试接口加密实战,框架撸码.......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 如果接口测试仅仅只…

【驱动开发】Windows过滤平台(WFP,Windows Filtering Platform)

文章目录Windows的发展历程TDI简介WFP简介用户态基础过滤引擎&#xff08;BFE&#xff09;内核态过滤引擎&#xff08;KMFE&#xff09;垫片&#xff08;Shim&#xff09;分层&#xff08;Layer&#xff09;子层&#xff08;Sub Layer&#xff09;过滤器&#xff08;Filter&…

【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)

可在系列教程的基础上继续开发&#xff0c;也可以单独使用 【微信小程序-原生开发】系列教程 效果预览 代码实现 点击触发生成海报 在活动详情页&#xff0c;指定点击某图标/按钮&#xff0c;触发跳转到生成海报的页面 pages\components\party\detail\index.js getPoster() …

OpenTex 企业内容管理平台

OpenText 企业内容管理平台 将内容服务与领先应用程序集成&#xff0c;弥合内容孤岛、加快信息流并扩大治理 什么是内容服务集成&#xff1f; 内容服务集成通过将内容管理平台与处于流程核心的独立应用程序和系统连接起来&#xff0c;支持并扩展了 ECM 的传统优势。 最好的内…

【通过Cpython3.9源码看看python字符串对象的创建】

CPython源码解析之PyUnicode_New函数实现 简介 PyUnicode_New是Python源码中用于创建Unicode字符串对象的函数&#xff0c;定义在UnicodeObject.c文件中。该函数接受一个长度参数size和最大字符值参数maxchar(根据传入的最大字符值 maxchar 确定新创建的字符串对象所需的存储…