容器篇(JavaSE - 单列集合)(持续更新迭代)

news2024/11/6 7:06:54

作者:研J小政

课堂:wclass

(有什么弊端请私信我,目前参考众多资料精华整理过程过中)

章节:单列集合!

进度:持续更新迭代!

录课状态:待录

参考文献

有意者可加

一、Collection 接口

1. 简介

Java的 Collection 框架是一组用于存储和操作对象的接口和类。

它提供了一种方便的方式来管理和操作数据集合。

Collection是Java集合框架的根接口,它定义了一些基本的操作和行为,如添加、删除、遍历等。

它有两个主要的子接口:List 和 Set

  • List是一个有序的集合,可以包含重复元素。它提供了按索引访问、插入、删除等操作。

常见的实现类有ArrayList、LinkedList和Vector。

  • Set是一个不允许包含重复元素的集合。它提供了高效的元素查找和去重。

常见的实现类有HashSet、TreeSet和LinkedHashSet。

二、List 接口

1. 简介

java.util.List接口继承自Collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对

象称为List集合,在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中

可以通过索引来访问集合中的指定元素,另外List集合还有一个特点就是元素有序,即元素的存入顺序和取

出顺序一致。

2. 特点

  • 有序
    • 存取有顺序
  • 有下标
    • 是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引一个道理)
  • 可以重复
    • 添加的元素可以重复

三、Set 接口

Set 接口继承自 Collection 接口,并提供了不允许重复元素的集合。

以下是一些常用的 Set 接口方法:

  • add(E element): 添加元素到集合中。
  • contains(Object obj): 判断集合是否包含指定元素。
  • remove(Object obj): 从集合中移除指定元素。
  • size(): 返回集合的大小。

以下是一个使用 HashSet 实现 Set 接口的示例代码:

import java.util.HashSet;
import java.util.Set;

public class SetExample {
    public static void main(String[] args) {
        Set<String> fruits = new HashSet<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        fruits.add("Apple"); // 重复元素,不会被添加

        System.out.println("Fruits: " + fruits);

        fruits.remove("Banana");
        System.out.println("Fruits after removal: " + fruits);

        boolean containsApple = fruits.contains("Apple");
        System.out.println("Contains Apple: " + containsApple);
    }
}

在上述示例中,我们创建了一个 HashSet 实例,并添加了一些水果。

由于 HashSet 不允许重复元素,所以重复的苹果不会被添加到集合中。

然后,我们从集合中移除了一个元素,并判断集合是否包含苹果。

最后,我们打印了集合的内容。

四、Queue 接口

1. 什么是队列?

队列是一种特殊的线性表,遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删

除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除;比如我们常用的

LinkedList 集合,它实现了Queue 接口,因此,我们可以理解为LinkedList 就是一个队列;

2. java队列特性

队列主要分为阻塞和非阻塞,有界和无界、单向链表和双向链表之分;

2.1 阻塞和非阻塞

阻塞队列

入列(添加元素)时,如果元素数量超过队列总数,会进行等待(阻塞),待队列的中的元素出列后,元素数量未超

过队列总数时,就会解除阻塞状态,进而可以继续入列;

出列(删除元素)时,如果队列为空的情况下,也会进行等待(阻塞),待队列有值的时候即会解除阻塞状态,进而

继续出列;

阻塞队列的好处是可以防止队列容器溢出;只要满了就会进行阻塞等待;也就不存在溢出的情况;

只要是阻塞队列,都是线程安全的;

非阻塞队列

不管出列还是入列,都不会进行阻塞,

入列时,如果元素数量超过队列总数,则会抛出异常,

出列时,如果队列为空,则取出空值;

一般情况下,非阻塞式队列使用的比较少,一般都用阻塞式的对象比较多;

阻塞和非阻塞队列在使用上的最大区别就是阻塞队列提供了以下2个方法:

  • 出队阻塞方法 : take()
  • 入队阻塞方法 : put()

2.2 有界和无界

有界:有界限,大小长度受限制

无界:无限大小,其实说是无限大小,其实是有界限的,只不过超过界限时就会进行扩容,就行ArrayList 一样,

在内部动态扩容

2.3 单向链表和双向链表

单向链表 : 每个元素中除了元素本身之外,还存储一个指针,这个指针指向下一个元素;

双向链表 :除了元素本身之外,还有两个指针,一个指针指向前一个元素的地址,另一个指针指向后一个

元素的地址;

3. java 队列接口继承图

4. 队列常用方法

add

增加一个元索

如果队列已满,则抛出一个IIIegaISlabEepeplian异常

remove

移除并返回队列头部的元素

如果队列为空,则抛出一个NoSuchElementException异常

element

返回队列头部的元素

如果队列为空,则抛出一个NoSuchElementException异常

offer

添加一个元素并返回true

如果队列为空,则返回null

poll

移除并返问队列头部的元素

如果队列为空,则返回null

peek

返回队列头部的元素

如果队列为空,则返回null

put

添加一个元素

如果队列满,则阻塞

take

一次性取出队列所有元素

如果队列为空,则阻塞

drainTo(list)

一次性取出队列所有元素

知识点: remove、element、offer 、poll、peek 其实是属于Queue接口。

5. 非阻塞队列

5.1 ConcurrentLinkedQueue

单向链表结构的无界并发队列, 非阻塞队列,由CAS实现线程安全,内部基于节点实现

5.2 ConcurrentLinkedDeque

双向链表结构的无界并发队列, 非阻塞队列,由CAS实现线程安全

5.3 PriorityQueue

内部基于数组实现,线程不安全的队列

6. 阻塞队列

6.1 DelayQueue

一个支持延时获取元素的无界阻塞队列

6.2 LinkedTransferQueue

一个由链表结构组成的无界阻塞队列

6.3 ArrayBlockingQueue

有界队列,阻塞式,初始化时必须指定队列大小,且不可改变;,底层由数组实现;

6.4 SynchronousQueue

最多只能存储一个元素,每一个put操作必须等待一个take操作,否则不能继续添加元素

6.3 PriorityBlockingQueue

一个带优先级的队列,而不是先进先出队列。元素按优先级顺序被移除,而且它也是无界的,也就是没有容量上

限,虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError

错误;

五、Deque 接口

1. 普通队列

1.1. 简介

队列在 Queue 接口已经说过,不免讲解两次,加深印象!

队列:只可以在一段进行插入操作,在另一端进行删除操作的线性表,队列具有先进先出的特性,在插入

操作的一端称作队尾,进行删除操作的一端称作队头。

1.2. Queue 接口(回顾)

如上图:

Queue(队列)是一个接口,底层是一个双向链表来实现的,所以Queue不能直接实例化一个对象,

只能是接口引用一个具体类(LinkedList)的方式来实例化。

1.3. 常用API

方法名

描述

boolean offer(E e)

入队列

E poll()

出队列

peek()

获取队头元素

int size()

获取队列中的有效元素个数

boolean isEmpty()

判断队列是否为空

1.4. 方法使用演示

public static void main(String[] args) {
    //尾插法和头部删除
    MyQueue queue = new MyQueue();
    queue.offer(1);
    queue.offer(2);
    queue.offer(3);
    System.out.println(queue.peek());//1
    System.out.println(queue.poll());//1
    System.out.println(queue.peek());//2
    System.out.println(queue.isEmpty());//false
    System.out.println(queue.usedSize);//3
}

1.5. 队列的模拟实现

注:双向链表是最合适实现一个队列的,双向链表可以在尾部插入,也可以在尾部进行删除,因为每个节

点都有前驱和后继节点,插入和删除的时间复杂度都是O(1),但是如果是单链表此时只能使用尾插法插

入,使用头删法(在头部进行删除)时间复杂度才是O(1)

//单链表实现一个队列
public class MyQueue {
    static class Node {
        public int val;
        public Node next;
        public Node(int val) {
            this.val = val;
        }
    }
    public Node head;
    public Node last;
    public int usedSize;
    //入队
    public void offer(int val) {
        Node node = new Node(val);
        if (head == null) {
            head = node;
            last = node;
        }else {
            last.next = node;
            last = node;
        }
        usedSize++;
    }
    //出队
    public int poll() {
        if (isEmpty()) {
            throw new EmptyException("队列是空的!");
        }
        int ret = head.val;
        head = head.next;
        if (head == null) {
            last = null;//如果只有一个节点,那么last也要置空
        }
        usedSize--;
        return ret;
    }
    //判断队列是否为空
    public boolean isEmpty() {
        return usedSize == 0;
    }
    //获取队列队顶元素
    public int peek() {
        if (isEmpty()) {
            throw new EmptyException("队列是空的!");
        }
        return head.val;
    }
    //获取队列有效元素的个数
    public int getUsedSize() {
        return usedSize;
    }
}

1.6. 顺序普通队列的缺点

如下图:

此时一个数组实现的顺序队列正在一边入队元素,一边出队元素,如果队列中的元素满了,此时元素再进

行出队,但是后边的元素是入不进来的,虽然前面的格子空出来了,但是此时元素只能从队尾进入,队头

出,可以看出,此时的队列的利用效率不是很高。

2. 循环队列

2.1 循环队列也是一种数据结构

基于上述队列的缺点,此时就有了循环队列,如下图:

2.2 是一个类似圆形的数组:

描述

1. 有front指针和rear指针同时指向数组的0下标,入队元素就让rear指针往后走一个,之后出队元素时,就让front指针向后移动。

2. 当循环队列满了,此时rear指针可以往前走一步,到达0下标,然后继续入队元素。

2.3 所以此时有两个问题:

描述

1. 当队列满,如何让rear指针指向0下标?

2. 当队列满时,rear = front;当队列为空时,rear = front,所以如何判断队列的空和满?

  1. 每次入队元素或者出队元素时,让 rear =(rear + 1)% queue.size(),front =(front + 1)% queue.size(),而不是简单的rear++,front++,所以就可以让rear下标和front下标在走到最后一个位置时,再往后走一步就又到了0下标的位置。
  2. 通过浪费一个空间来区分队列的空和满,如果rear指针的下一个就是front(0下标),此时就认为队列为满,当rear = front时,此时队列为空。(或者使用usedSize来记录当前元素个数也可以)。

2.4 循环队列的实现 (力扣)

package Review;
// 循环队列底层就是一个数组
// 浪费掉最后一个空间来表示队列是否是满的
// 就是每次都让rear往后走一步,之后进行判断如果rear的下一个位置就是0下标
// 此时队列就是满的,如果front == rear,此时队列是空的
class MyCircularQueue {
    private int[] elem;
    private int front;//队列的头
    private int rear;//队列的尾
    public MyCircularQueue(int k){
        this.elem = new int[k+1];
    }
    public boolean enQueue(int value) {
        //1.检查队列是否是满的
        if (isFull()) {
            return false;
        }
        //2.入队元素,之后让rear引用往后走一步
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        return true;
    }
    public boolean deQueue() {
        if (isEmpty()) {
            return false;
        }
        //front++;
        front = (front + 1) % elem.length;
        return true;
    }
    public int Front() {
        if (isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    public int Rear() {
        if (isEmpty()) return -1;
        //return elem[rear - 1];
        //此时还有一个问题需要注意,如果rear到了0下标,之后就数组越界了
        //数组是没有-1下标的,
        //也就是让rear返回数组的最后一个下标
        int index = (rear == 0) ? elem.length - 1 : rear - 1;
        return elem[index];
    }
    public boolean isFull() {
        return (rear + 1) % elem.length == front;
    }
    public boolean isEmpty() {
        return front == rear;
    }
}

3. 双端队列(Deque)

3.1. 简介

双端队列就是可以在两端都可以入队,也可以出队的队列,元素可以从队头入队和出队,

也可以从队尾出队和入队。

3.2. 双端队列的使用

在实际使用中,Deque接口使用的是比较多的,栈和队列都可以使用该接口,这个接口中有栈的方法,

也有队列的方法

    public static void main9(String[] args) {
        //底层是一个双向链表
        Deque<Integer> deque = new LinkedList<>();
        //数组实现的双端队列:底层就是一个数组
        Deque<Integer> deque1 = new ArrayDeque<>();
        //顺序的双端队列也可以当作栈来使用
        Deque<Integer> stack = new ArrayDeque<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);//顺序的双端队列(底层是用数组来实现的)也提供了栈的相关的方法
 
    }
    public static void main8(String[] args) {
        //双端队列
        Deque<Integer> deque = new LinkedList<>();
        //普通队列
        //Queue中既有offer方法,也有add方法,add在无法添加一个元素时,会抛出一个异常
        //offer方法优于add方法,如果无法添加元素,offer方法不会抛出异常
        Queue<Integer> queue = new LinkedList<>();
        //链式栈  虽然是具体的类但是里面有栈的方法
        //LinkedList类中的方法是最多的,因为它实现了很多接口,此时一定会重写接口中的方法
        LinkedList<Integer> stack = new LinkedList<>();
        //双向链表
        List<Integer> list = new LinkedList<>();
        //其他的都是使用接口来引用的:只有接口中的方法
    }

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

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

相关文章

GLM-4开源发布:实力赶超Llama3,多模态能力媲美GPT4V,MaaS平台全面升级

最新版本大模型&#xff0c;6 分钱 100 万 Token。 今天上午&#xff0c;在 AI 开放日上&#xff0c;备受关注的大模型公司智谱 AI 公布了一系列行业落地数字&#xff1a; 根据最新的统计数据&#xff0c;智谱 AI 大模型开放平台目前已经获得 30 万注册用户&#xff0c;日均调用…

GPT4的代码生成能力能不能取代一个月薪5000水平的码农?

GPT-4 的代码生成能力确实非常强大&#xff0c;但它是否能取代一个月薪 5000 元水平的码农&#xff0c;还要看具体情况。以下是几个关键点&#xff1a; 代码质量和复杂性&#xff1a;GPT-4 &#xff08;升级教程&#xff09;可以生成很多常见的代码片段和解决方案&#xff0c;…

【CSP:202305-1】重复局面(Java)

题目链接 202305-1 重复局面 题目描述 样例输入&#xff1a; 8 ******** ******pk *****r*p p*pQ**** ******** **b*B*PP ****qP** **R***K* ******** ******pk *****r*p p*pQ**** *b****** ****B*PP ****qP** **R***K* ******** ******pk *****r*p p*p***** *b**Q*** ****B…

FPGA第 6 篇,PFGA基础数字电路,PFGA基础知识数字电路, 组合逻辑电路和时序逻辑电路,数字电路与模拟电路

前言 FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;是一种高度灵活的硬件器件&#xff0c;可以通过编程配置其内部的逻辑单元和连接&#xff0c;适用于各种数字电路设计和实现。在学习FPGA之前&#xff0c;掌握数字电路的基础知识是…

【AI】Ollama+OpenWebUI+llama3本地部署保姆级教程,没有连接互联网一样可以使用AI大模型!!!

1 电脑配置 操作系统CPU内存Windows 10以上12核16GB 2 安装Ollama 2.1 下载Ollama 登录Ollama官网下载Ollama安装包 GitHub&#xff1a;https://github.com/ollama/ollama?tabreadme-ov-file 2.2 安装Ollama Windows下安装Ollama很简单&#xff0c;双击运行安装文件即…

ES6笔记总结(Xmind格式):第三天

Xmind鸟瞰图&#xff1a; 简单文字总结&#xff1a; ES6知识总结&#xff1a; Promise的使用: 1.使用 new Promise() 构造函数来创建一个 promise 对象 2.接受两个函数作为参数&#xff1a;resolve 和 reject ①resolve 函数在异步操作成功完成时调用&#xf…

[000-01-022].第06节:RabbitMQ中的交换机介绍

1.什么是Exchanges(交换机&#xff09;: 1.RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上&#xff0c;通常生产者甚至都不知道这些消息传递传递到了哪些队列中2.生产者只能将消息发送到交换机(exchange)&#xff0c;交换机工作的内容非常…

Axure版需求文档:原型版PRD模板

行业原型预览链接&#xff1a;&#xff08;请与班主任联系获取原型文档&#xff09; 文件类型&#xff1a;.rp 支持版本&#xff1a;Axrure RP 8 文档名称&#xff1a;Axure需求规格说明书-PRD模版 文件大小&#xff1a;3.50 MB 目录内容介绍 文档内容介绍 回复 “211103”…

设计师具备怎样的专业素养,才能走得更远?

设计师具备怎样的专业素养&#xff0c;才能走得更远&#xff1f; 带着这样的思考&#xff0c;我们邀请到莱佛士设计学院知名校友Regina Fang——新加坡独立品牌NEWFOUND纽方品牌创始人&#xff0c;为大家解读设计师在学习技能以及创业的过程&#xff0c;需要具备怎样的专业素养…

九、 系统安全(考点篇)试题

信息安全系统&#xff1a;技术方面有了&#xff0c;管理方面有了&#xff0c;看选项里&#xff0c;A、C、D都是需求跟安全扯不上多大关系。选B 备份和恢复跟安全沾边&#xff0c;迁移是旧系统数据迁到新系统&#xff0c;测试跟安全更远了。选C 选D机密性&#xff1b;选D可控性…

城市轨道交通能耗管理

随着城市轨道交通线网规模的扩大&#xff0c;其能源消耗也日益增加。车站作为城市轨道交通系统的“单元”&#xff0c;能耗管理效应的发挥主要从“车站”人手。同时&#xff0c;为助推国家双碳战略目标实施&#xff0c;文章结合《中国城市轨道交通智慧城轨发展纲要》及应用需求…

fragment生命周期

fragment生命周期 onAttach()始终在任何Lifecycle 状态更改之前调用&#xff0c;所以onAttach()在onCreate()之前调用。 onAttach(): Fragment 被附加到 Activity 时调用。在这个阶段&#xff0c;Fragment 可以获取 Activity 的上下文。 onCreate(): 在 Fragment 创建时调用…

旅游巴士(bus)【CSPJ2023】

题目描述 小Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。 旅游景点的地图共有n 处地点&#xff0c;在这些地点之间连有m 条道路。其中1 号地点为景区入口&#xff0c;n 号地点为景区出口。我们把一天当中景区开门营业的时间记为0 时刻&#xff0c;则从0 时刻…

[大模型]Conda在线安装-Langchain-Chatchat-V0.3

文章目录 官方仓库地址历史问题 使用conda在线安装启动项目疑问解答为什么运行命令是chatchat&#xff1f; 移动conda与重命名conda 官方仓库 地址 https://github.com/chatchat-space/Langchain-Chatchat历史问题 问题中可能包含着旧版本&#xff08;Langchain-Chatchat-V0…

打通Vue3+Flask(python3)+Mysql-实现简单数据交互

一、需要准备的工具 下载python3&#xff0c;Vscode&#xff0c;pycharm&#xff08;这里用的社区版&#xff09;&#xff0c;phpstudy_pro&#xff0c;Node.js&#xff08;建议下载长期支持版本&#xff0c;版本不宜过低&#xff0c;比如18,20&#xff09;&#xff0c;Vue.js…

LearnOpenGL——HDR、Bloom学习笔记

LearnOpenGL——HDR、Bloom学习笔记 HDR一、基本概念二、浮点帧缓冲 Floating Point Framebuffer三、色调映射 Tone MappingReinhard色调映射曝光色调映射 Bloom一、提取亮色二、高斯模糊三、将两个纹理进行混合 HDR 一、基本概念 显示器被限制只能显示0.0-1.0的颜色&#xf…

“AI+Security”系列第2期(四):AI/机器学习供应链攻击

近日&#xff0c;由安全极客、Wisemodel 社区和 InForSec 网络安全研究国际学术论坛联合主办的“AISecurity”系列第二期线上活动如期举行。此次活动的主题为“对抗&#xff01;大模型自身安全的攻防博弈”&#xff0c;旨在深入探讨和分析人工智能和机器学习领域中的安全问题。…

武汉流星汇聚:亚马逊返校季学习用品热销,精准布局助力卖家成功

随着夏日的余温逐渐消散&#xff0c;新学期的钟声悄然临近&#xff0c;家长与学生们纷纷投入到新学期的准备工作中&#xff0c;而亚马逊作为全球领先的电商平台&#xff0c;再次迎来了学习用品销售的火爆季节。数据显示&#xff0c;过去30天内&#xff0c;“back to school”&a…

罗德与施瓦茨(RS)RTP164、RTP134,RTP084,RTP064示波器

罗德示波器系列RTP164租赁RTP134收购RTP084/RTP064/RTP034 概述 数字示波器是数据采集&#xff0c;A/D转换&#xff0c;软件编程等一系列的技术制造出来的高性能示波器&#xff0c;是电子类学科设计、制造和维修产品过程中不可或缺的工具。R&SRTP164示波器可以提供16GHz的…

U盘安装Ubuntu24.04,乌邦图,UltralISO

文章目录 前言通过UltraISO&#xff0c;制作启动U盘下载镜像制作工具UltraISO(软碟通)下载ubuntu镜像文件制作启动U盘 安装ubuntu设置root密码&#xff0c;并登陆root 前言 在Ubuntu作为主流的linux系统&#xff0c;有时候使用VMware安装使用&#xff0c;总归有一定的性能损耗…