Java_集合进阶(Collection和List系列)

一、集合概述和分类

1.1 集合的分类

已经学习过了ArrayList集合,但是除了ArrayList集合,Java还提供了很多种其他的集合,如下图所示:
在这里插入图片描述

我想你的第一感觉是这些集合好多呀!但是,我们学习时会对这些集合进行分类学习,如下图所示:一类是单列集合元素是一个一个的,另一类是双列集合元素是一对一对的。

在这里插入图片描述
Collection是单列集合的根接口,Collection接口下面又有两个子接口List接口、Set接口,List和Set下面分别有不同的实现类,如下图所示:
在这里插入图片描述
可以自己写代码验证一下,各种集合的特点

//简单确认一下Collection集合的特点
ArrayList<String> list = new ArrayList<>(); //存取顺序一致,可以重复,有索引
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
System.out.println(list); //[java1, java2, java1, java2] 

HashSet<String> list = new HashSet<>(); //存取顺序不一致,不重复,无索引
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
list.add("java3");
System.out.println(list); //[java3, java2, java1] 

1.2 Collection集合的常用方法

在这里插入图片描述

接下来,我们学习一下Collection集合的一些常用方法,这些方法所有Collection实现类都可以使用。 这里我们以创建ArrayList为例,来演示

Collection<String> c = new ArrayList<>();
//1.public boolean add(E e): 添加元素到集合
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c); //打印: [java1, java1, java2, java2, java3]
 
//2.public int size(): 获取集合的大小
System.out.println(c.size()); //5
 
//3.public boolean contains(Object obj): 判断集合中是否包含某个元素
System.out.println(c.contains("java1")); //true
System.out.println(c.contains("Java1")); //false
 
//4.pubilc boolean remove(E e): 删除某个元素,如果有多个重复元素只能删除第一个
System.out.println(c.remove("java1")); //true
System.out.println(c); //打印: [java1,java2, java2, java3]
 
//5.public void clear(): 清空集合的元素
c.clear(); 
System.out.println(c); //打印:[]
 
//6.public boolean isEmpty(): 判断集合是否为空 是空返回true 反之返回false
System.out.println(c.isEmpty()); //true
 
//7.public Object[] toArray(): 把集合转换为数组
Object[] array = c.toArray();
System.out.println(Arrays.toString(array)); //[java1,java2, java2, java3]
 
//8.如果想把集合转换为指定类型的数组,可以使用下面的代码
String[] array1 = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array1)); //[java1,java2, java2, java3]
 
//9.还可以把一个集合中的元素,添加到另一个集合中
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2); //把c2集合中的全部元素,添加到c1集合中去
System.out.println(c1); //[java1, java2, java3, java4]

最后,我们总结一下Collection集合的常用功能有哪些,ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet集合都可以调用下面的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二、Collection遍历方式

各位同学,接下来我们学习一下Collection集合的遍历方式。有同学说:“集合的遍历之前不是学过吗?就用普通的for循环啊? “ 没错!之前是学过集合遍历,但是之前学习过的遍历方式,只能遍历List集合,不能遍历Set集合,因为以前的普通for循环遍历需要索引,只有List集合有索引,而Set集合没有索引。

所以我们需要有一种通用的遍历方式,能够遍历所有集合。

2.1 迭代器遍历集合

在这里插入图片描述

接下来学习的迭代器就是一种集合的通用遍历方式。

代码写法如下:

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]
 
//第一步:先获取迭代器对象
//解释:Iterator就是迭代器对象,用于遍历集合的工具)
Iterator<String> it = c.iterator();
 
//第二步:用于判断当前位置是否有元素可以获取
//解释:hasNext()方法返回true,说明有元素可以获取;反之没有
while(it.hasNext()){
    //第三步:获取当前位置的元素,然后自动指向下一个元素.
    String e = it.next();
    System.out.println(s);
}

迭代器代码的原理如下:

  • 当调用iterator()方法获取迭代器时,当前指向第一个元素
  • hasNext()方法则判断这个位置是否有元素,如果有则返回true,进入循环
  • 调用next()方法获取元素,并将当月元素指向下一个位置,
  • 等下次循环时,则获取下一个元素,依此内推

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我们再总结一下,使用迭代器遍历集合用到哪些方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2 增强for遍历集合

同学们刚才我们学习了迭代器遍历集合,但是这个代码其实还有一种更加简化的写法,叫做增强for循环。

格式如下:
在这里插入图片描述

需要注意的是,增强for不光可以遍历集合,还可以遍历数组。接下来我们用代码演示一em.o下:

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");

//1.使用增强for遍历集合
for(String s: c){
    System.out.println(s); 
}
 
//2.再尝试使用增强for遍历数组
String[] arr = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
for(String name: arr){
    System.out.println(name);
}

2.3 forEach遍历集合

在JDK8版本以后还提供了一个forEach方法也可以遍历集合,如果下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们发现forEach方法的参数是一个Consumer接口,而Consumer是一个函数式接口,所以可以传递Lambda表达式

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
 
//调用forEach方法
//由于参数是一个Consumer接口,所以可以传递匿名内部类
c.forEach(new Consumer<String>{
    @Override
    public void accept(String s){
        System.out.println(s);
    }
});

//也可以使用lambda表达式对匿名内部类进行简化
c.forEach(s->System.out.println(s)); //[赵敏, 小昭, 素素, 灭绝]

在这里插入图片描述

2.4 遍历集合案例

接下来,我们看一个案例,在集合中存储自定义的对象,并遍历。具体要求如下
在这里插入图片描述

首先,我们得写一个电影类,用来描述每一步电影应该有哪些信息。

public class Movie{
    private String name; //电影名称
    private double score; //评分
    private String actor; //演员
    //无参数构造方法
    public Movie(){}
    //全参数构造方法
    public Movie(String name, double score, String actor){
        this.name=name;
        this.score=score;
        this.actor=actor;
    }
    //...get、set、toString()方法自己补上..
}

接着,再创建一个测试类,完成上面的需求

public class Test{
    public static void main(String[] args){
        Collection<Movie> movies = new ArrayList<>();
        movies.add(new MOvie("《肖申克的救赎》", 9.7, "罗宾斯"));
        movies.add(new MOvie("《霸王别姬》", 9.6, "张国荣、张丰毅"));
        movies.add(new MOvie("《阿甘正传》", 9.5, "汤姆汉克斯"));
         
        for(Movie movie : movies){
            System.out.println("电影名:" + movie.getName());
            System.out.println("评分:" + movie.getScore());
            System.out.println("主演:" + movie.getActor());
        }
    }
}

以上代码的内存原理如下图所示:当往集合中存对象时,实际上存储的是对象的地址值
在这里插入图片描述

集合中存储的是元素对象的地址。

三、List系列集合

前面我们已经把Collection通用的功能学习完了,接下来我们学习Collection下面的一个子体系List集合。如下图所示:
在这里插入图片描述

3.1 List集合的常用方法

List集合是索引的,所以多了一些有索引操作的方法,如下图所示:
在这里插入图片描述

//1.创建一个ArrayList集合对象(有序、有索引、可以重复)
List<String> list = new ArrayList<>();
list.add("蜘蛛精");
list.add("至尊宝");
list.add("至尊宝");
list.add("牛夫人"); 
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
 
//2.public void add(int index, E element): 在某个索引位置插入元素
list.add(2, "紫霞仙子");
System.out.println(list); //[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人]
 
//3.public E remove(int index): 根据索引删除元素, 返回被删除的元素
System.out.println(list.remove(2)); //紫霞仙子
System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
 
//4.public E get(int index): 返回集合中指定位置的元素
System.out.println(list.get(3));
 
//5.public E set(int index, E e): 修改索引位置处的元素,修改后,会返回原数据
System.out.println(list.set(3,"牛魔王")); //牛夫人
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]

3.2 List集合的遍历方式

List集合相比于前面的Collection多了一种可以通过索引遍历的方式,所以List集合遍历方式一共有四种:

  • 普通for循环(只因为List有索引)
  • 迭代器
  • 增强for
  • Lambda表达式
List<String> list = new ArrayList<>();
list.add("蜘蛛精");
list.add("至尊宝");
list.add("糖宝宝");
 
//1.普通for循环
for(int i = 0; i< list.size(); i++){
    //i = 0, 1, 2
    String e = list.get(i);
    System.out.println(e);
}
 
//2.增强for遍历
for(String s : list){
    System.out.println(s);
}
 
//3.迭代器遍历
Iterator<String> it = list.iterator();
while(it.hasNext()){
    String s = it.next();
    System.out.println(s);
}
 
//4.lambda表达式遍历
list.forEach(s->System.out.println(s));

3.3 ArrayList底层的原理

在这里插入图片描述

ArrayList集合底层是基于数组结构实现的,也就是说当你往集合容器中存储元素时,底层本质上是往数组中存储元素。 特点如下:
在这里插入图片描述

我们知道数组的长度是固定的,但是集合的长度是可变的,这是怎么做到的呢?原理如下:
在这里插入图片描述

数组扩容,并不是在原数组上扩容(原数组是不可以扩容的),底层是创建一个新数组,然后把原数组中的元素全部复制到新数组中去。
在这里插入图片描述

3.4 LinkedList底层原理

LinkedList底层是双链表结构,链表结构是由一个一个的节点组成,一个节点由数据值、下一个元素的地址组成。如下图所示
在这里插入图片描述
假如,现在要在B节点和D节点中间插入一个元素,只需要把B节点指向D节点的地址断掉,重新指向新的节点地址就可以了。如下图所示:
在这里插入图片描述

假如,现在想要把D节点删除,只需要让C节点指向E节点的地址,然后把D节点指向E节点的地址断掉。此时D节点就会变成垃圾,会把垃圾回收器清理掉。
在这里插入图片描述

上面的链表是单向链表,它的方向是从头节点指向尾节点的,只能从左往右查找元素,这样查询效率比较慢;还有一种链表叫做双向链表,不光可以从做往右找,还可以从右往左找。如下图所示:
在这里插入图片描述

LinkedList集合是基于双向链表实现了,所以相对于ArrayList新增了一些可以针对头尾进行操作的方法,如下图示所示:
在这里插入图片描述

3.5 LinkedList集合的应用场景

刚才我们学习了LinkedList集合,那么LInkedList集合有什么用呢?可以用它来设计栈结构、队列结构。

  • 我们先来认识一下队列结构,队列结构你可以认为是一个上端开口,下端也开口的管子的形状。元素从上端入队列,从下端出队列。
    在这里插入图片描述

入队列可以调用LinkedList集合的addLast方法,出队列可以调用removeFirst()方法.

//1.创建一个队列:先进先出、后进后出
LinkedList<String> queue = new LinkedList<>();
//入对列
queue.addLast("第1号人");
queue.addLast("第2号人");
queue.addLast("第3号人");
queue.addLast("第4号人");
System.out.println(queue);
 
//出队列
System.out.println(queue.removeFirst());    //第4号人
System.out.println(queue.removeFirst());    //第3号人
System.out.println(queue.removeFirst());    //第2号人
System.out.println(queue.removeFirst());    //第1号人
  • 接下来,我们再用LinkedList集合来模拟一下栈结构的效果。还是先来认识一下栈结构长什么样。栈结构可以看做是一个上端开头,下端闭口的水杯的形状。

    元素永远是上端进,也从上端出,先进入的元素会压在最底下,所以栈结构的特点是先进后出,后进先出
    在这里插入图片描述

有没有感觉栈结构很像,手枪的子弹夹呀!!第一个压进入的子弹在最底下,最后一个才能打出来,最后一个压进入的子弹在最顶上,第一个打出来。

接着,我们就用LinkedList来模拟下栈结构,代码如下:

//1.创建一个栈对象
LinkedList<String> stack = new ArrayList<>();
//压栈(push) 等价于 addFirst()
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack); //[第4颗子弹, 第3颗子弹, 第2颗子弹,第1颗子弹]
 
//弹栈(pop) 等价于 removeFirst()
System.out.println(statck.pop()); //第4颗子弹
System.out.println(statck.pop()); //第3颗子弹
System.out.println(statck.pop()); //第2颗子弹
System.out.println(statck.pop()); //第1颗子弹
 
//弹栈完了,集合中就没有元素了
System.out.println(list); //[]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

读书笔记产品经理学习笔记1-忘掉技术,先看客户需求

技术到产品思维的转换 以前做技术的时候&#xff0c;扮演的角色是怎样多快好省的完成开发。现在做产品了&#xff0c;你得自己定产品方案&#xff0c;让别人来开发。最重要的是先弄清楚客户的需求是什么&#xff0c;要解决什么问题&#xff0c;再看产品怎么设计&#xff0c;然…

用ImageJ处理高斯光束的光斑

文章目录 图像显示图像裁剪高斯拟合 图像显示 ImageJ是著名的科研图像处理工具&#xff0c;提供了非常强大的分析功能&#xff0c;处理光斑图像简直是小菜一碟。这里推荐下载fiji&#xff0c;是内置了大量插件的ImageJ&#xff0c;可以满足各种科研上的图像处理需求。 打开一…

RTOS中断管理的简单应用

我们在stm32f103c8t6单片机上验证RTOS中断管理&#xff0c;利用stm32cube进行RTOS的配置。裸机的时钟源默认是 SysTick&#xff0c;但是开启 FreeRTOS 后&#xff0c;FreeRTOS会占用 SysTick &#xff08;用来生成1ms 定时&#xff0c;用于任务调度&#xff09;&#xff0c;所以…

maven学习和maven聚合工程搭建

1.学习maven maven的概念 项目管理工具 &#xff0c;对jar进行依赖管理&#xff0c;编译&#xff0c;打包&#xff0c;单元测试&#xff0c;安装&#xff0c;部署&#xff0c;贯穿整个项目 为什么要学maven 要解决的问题&#xff1a; 不同的开发工具开发出来的项目目录结构…

智能优化算法应用:基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于非洲秃鹫算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.非洲秃鹫算法4.实验参数设定5.算法结果6.…

PostgresSQL数据库中分区和分表的区别以及PostgresSQL创建表分区分表示例

1.分区分表理解 数据库分区和分表都是数据库中常用的数据分散存储技术&#xff0c;但它们的实现方式和应用场景有所不同。 分表&#xff1a;将一个大的表拆分成多个小的表&#xff0c;每个子表存储一部分数据。分表可以减轻单个表的数据量&#xff0c;提高查询效率&#xff0c…

七、W5100S/W5500+RP2040之MicroPython开发<HTTP Client示例>

文章目录 1. 前言2. 相关网络信息2.1 简介2.2 原理2.3 请求方法2.4 应用 3. WIZnet以太网芯片4. HTTP Client通信示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代&#xff0c;Mic…

Swagger2接口测试文档

目录 一、Swagger简介 1.1 Swagger是什么&#xff1f; 1.2 为什么要用Swagger 1.3 Swagger注解 二、Spring集成Swagger 三、测试环境配置 一、Swagger简介 1.1 Swagger是什么&#xff1f; Swagger是一款RESTFUL接口的文档在线自动生成功能测试功能软件。Swagger是一个规…

Qt 国际化——创建中英文翻译步骤

Qt 国际化——创建中英文翻译步骤 说明&#xff1a;之前我的csdn博客&#xff0c;第一篇文章发表的就是Qt国际化的文章&#xff08;点击打开&#xff09;&#xff0c;写的也过于简单了&#xff1a; 今天&#xff0c;这篇文章再详细的记录下&#xff0c;中英文翻译的步骤。 一…

【Python】循环语句

一、while循环的基础语法 二、while循环的嵌套应用 三、while循环的嵌套案例 四、for循环的基础语法 五、for循环的嵌套应用 六、循环中断 : break和continue 一、while循环的基础语法 使用while循环的基础应用 while循环语句 while循环注意点 while的条件需得到布尔类型&am…

高通平台开发系列讲解(系统篇)系统关机流程

文章目录 一、关机流程图二、执行关机流程2.1、kernel_shutdown_prepare流程2.2、migrate_to_reboot_cpu流程2.3、syscore_shutdown流程2.4、machine_power_off流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要图解高通平台系统关机流程。 一、关机流程图…

Go后端开发 -- 环境搭建

Go后端开发 – 环境搭建 文章目录 Go后端开发 -- 环境搭建一、环境配置二、IDE的选择三、使用go mod构建项目1.初始化项目2.添加依赖项3.运行项目 四、环境报错1.VS Code中gopls报错 一、环境配置 Go官网下载地址&#xff1a;https://golang.org/dl/ https://go.dev/dl/ Go官方…

SpringSecurity深度解析与实践(1)

目录 引言1. SpringSecurity1.1 SpringSecurity简介1.2 SpringSecurity工作原理1.3.特点 2. SpringSecurity的快速使用总结 引言 SpringSecurity作为Spring框架中的一个重要组成部分&#xff0c;扮演着保护应用程序安全的重要角色。本文将深入探讨SpringSecurity的原理、使用方…

C# .Net学习笔记—— Expression 表达式目录树

一、什么是表达式目录树 &#xff08;1&#xff09;Expression我们称为是表达式树&#xff0c;是一种数据结构体&#xff0c;用于存储需要计算&#xff0c;运算的一种结构&#xff0c;这种结构可以只是存储&#xff0c;而不进行运算。通常表达式目录树是配合Lambda一起来使用的…

PySpark中DataFrame的join操作

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

常见可视化大屏编辑器有哪些?

前言&#xff1a; 在当今数字化时代&#xff0c;可视化大屏编辑器成为了数据展示和决策支持的重要工具。大屏编辑器不仅仅是数据的呈现&#xff0c;更是数据背后的故事的讲述者。它通过图表、图形和实时数据的呈现&#xff0c;为用户提供了全面的信息视图&#xff0c;帮助用户更…

【无人机学习篇】构建mavros机载电脑连接,从机载电脑获取pixhawk数据

&#xff08;本文基于的pixhawk版本&#xff1a;6X minibase V2.2 &#xff0c;固件&#xff1a;apm&#xff09; 整个的步骤&#xff08;baseline&#xff09;&#xff1a; 具体的每一步都可以在网上查到教程&#xff0c;这里只是梳理出一个流程。并且ubantu与ros的版本也不是…

Python - 深夜数据结构与算法之 Map Set

目录 一.引言 二.Map 与 Set 1.Hash Table 2.Hash Function 3.Hash Collisions 4.Java/Python Code 三.经典算法实战 1.Two-Sum [1] 2.Group-Anagrams [49] 3.Valid-Anagram [242] 四.总结 一.引言 前面介绍了列表 List 及其衍生的栈 Stack 与队列 Queue&#xff0…

VR全景技术在政务服务中有哪些应用,为政务服务带来什么便利

引言&#xff1a; 随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;全景技术正逐渐成为政务服务领域的一项重要工具。其独特的沉浸式体验为政务服务带来了全新的便利&#xff0c;提升了公众参与的积极性。 一、VR全景技术在政务服务中的应用 1.虚拟实景政务…

多表插入、删除操作(批量)——后端

多表插入 场景&#xff1a;当添加一个菜品时&#xff0c;还需要记录菜品的口味信息&#xff0c;因此需要对菜品表&#xff08;dish&#xff09;和口味表&#xff08;dish_flavor&#xff09;同时进行插入操作。 两个表的字段&#xff1a; 代码思路&#xff1a;由DishControll…