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>{@Overridepublic 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, 2String 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); //[]

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

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

相关文章

基于alibaba druid的血缘解析工具

基于alibaba druid的血缘解析 1、前言 仅仅对mysql数据库的select查询语句进行了血缘解析&#xff0c;该血缘解析包含了原始表字段、临时表字段和目标表字段的关联关系。 2、涉及到技术 主要使用了druid的如下接口对语法树进行解析&#xff1a; &#xff08;1&#xff09;…

JavaWeb笔记之前端开发CSS

一 、引言 1.1 CSS概念 层叠样式表(英文全称&#xff1a;Cascading Style Sheets)是一种用来表现HTML&#xff08;标准通用标记语言的一个应用&#xff09;或XML&#xff08;标准通用标记语言的一个子集&#xff09;等文件样式的计算机语言。CSS不仅可以静态地修饰网页&…

美颜技术详解:深入了解视频美颜SDK的工作机制

本文将深入探讨视频美颜SDK的工作机制&#xff0c;揭示其背后的科技奥秘和算法原理。 1.引言 视频美颜SDK作为一种集成到应用程序中的技术工具&#xff0c;通过先进的算法和图像处理技术&#xff0c;为用户提供令人印象深刻的实时美颜效果。 2.视频美颜SDK的基本工作原理 首…

SVN小白常见操作流程

SVN小白常见操作流程 一、什么是Subversion&#xff1f;二、TortoiseSVN客户端安装教程三、SVN 操作3.1 SVN Ckeckout(检出)3.2 Add(新增文件)3.3 SVN Commit(提交)3.4 SVN Update(更新操作)3.5SVN Delete(删除操作)3.6 SVN Revert to a revision(版本回溯)3.7 不同版本内容之间…

Jenkins 执行远程脚本的插件—SSH2 Easy

SSH2 Easy 是什么&#xff1f; SSH2 Easy 是一个 Jenkins 插件&#xff0c;它用于在 Jenkins 构建过程中通过 SSH2 协议与远程服务器进行交互。通过该插件&#xff0c;用户可以在 Jenkins 的构建过程中执行远程命令、上传或下载文件、管理远程服务器等操作。 以下是 SSH2 Eas…

vue3使用mock模拟后端接口

安装mock axios yarn add mock yarn add axios 新建在src/mockdata/automenu.js 模拟后端的json数据格式 import Mock from mockjs Mock.mock(/menu,get,{status: 200,menuList: [{id : 1,iconCls: "fa fa-window",name: 系统管理,url: /},{id: 2,icon: icon-j…

YOLOv8改进 | 主干篇 | 利用MobileNetV1替换Backbone(轻量化网络结构)

一、本文介绍 本文给大家带来的改进机制是MobileNetV1&#xff0c;其是专为移动和嵌入式视觉应用设计的轻量化网络结构。这些模型基于简化的架构&#xff0c;并利用深度可分离卷积构建轻量级深度神经网络&#xff0c;其引入了两个简单的全局超参数&#xff0c;用于在延迟和准确…

【C语言】指针详解(一)

目录 1.内存和地址 1.1内存 1.2如何理解编址 2.指针变量和地址 2.1取地址操作符&#xff08;&&#xff09; 2.2指针变量和解引用操作符&#xff08;*&#xff09; 2.2.1指针变量 2.2.2拆解指针类型 2.2.3解引用操作符 2.3指针变量大小 1.内存和地址 1.1内存 在讲内…

《数据分析-JiMuReport》积木报表详细入门教程

积木报表详细入门教程 一、JimuReport部署入门介绍 积木报表可以通过源码部署、SpringBoot集成、Docker部署以及各种成熟框架部署&#xff0c;具体可查看积木官方文档 当前采用源码部署&#xff0c;首先下载Jimureport-example-1.5.6 1 jimureport-example目录查看 使用ID…

自动气象监测站助力生活生产

随着科技的发展&#xff0c;我们的生活和生产方式正在发生着日新月异的变化。其中&#xff0c;WX-CQ12 自动气象监测站作为一项气象监测设备&#xff0c;正在发挥着越来越重要的作用。它不仅为我们提供了更加准确、实时的天气信息&#xff0c;还为农业、交通、旅游等领域提供了…

python flask+vue实现前后端图片上传

python flaskvue实现前后端图片上传 vue代码如下&#xff1a; <template><div><input type"file" change"handleFileChange"/><button click"uploadFile">上传</button><br><img :src"imageUrl&…

uniapp如何原生app-云打包

首先第一步&#xff0c;需要大家在HBuilder X中找到一个项目&#xff0c;然后呢在找到上面的发行选项 发行->原生App-云打包 选择完该选中的直接大包就ok。 大包完毕后呢&#xff0c;会出现一个apk包&#xff0c;这是后将这个包拖动发给随便一个人就行了。 然后接收到的那…

2-高可用-负载均衡、反向代理

负载均衡、反向代理 upstream server即上游服务器&#xff0c;指Nginx负载均衡到的处理业务的服务器&#xff0c;也可以称之为real server,即真实处理业务的服务器。 对于负载均衡我们要关心的几个方面如下&#xff1a; 上游服务器配置&#xff1a;使用upstream server配置上…

摄像头画面作为电脑桌面背景

1. 创建文件main.pyw&#xff0c;文件内容 import base64 import io import os import threading import tkinter as tkimport cv2 import pystray import win32api import win32con import win32gui from PIL import Image, ImageTk from pystray import MenuItem, Menuclass…

Linux之yum管理器

目录 yum管理器 yum相关指令 yum list yum list | grep yum install yum remove 拓展 1.yum install -y man-pages 2.切换yum源 3.yum install -y epel-release 4. yum install -y lrzsz rz指令 sz指令 在window系统上&#xff0c;我们会在电脑自带的应用商…

mac电脑安装虚拟机教程

1、准备一台虚拟机&#xff0c;安装CentOS7 常用的虚拟化软件有两种&#xff1a; VirtualBoxVMware 这里我们使用VirtualBox来安装虚拟机&#xff0c;下载地址&#xff1a;Downloads – Oracle VM VirtualBox 001 点击安装 002 报错&#xff1a;he installer has detected an…

Windows11编译VTM源码生成Visual Studio 工程

VTM介绍 VTM作为H266/VVC标准的官方参考软件&#xff0c;一直用作H266/VVC标准的研究和迭代。关于H2666/VVC标准的介绍、代码、提案、文档等&#xff0c;可以参考H266/VVC编码标准介绍。 官方代码地址&#xff1a; https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM&…

【GoLang】哪些大公司正在使用Go语言

你见过哪些令你膛目结舌的代码技巧&#xff1f; 文章目录 你见过哪些令你膛目结舌的代码技巧&#xff1f;前言&#xff1a;哪些大公司正在使用Go语言谷歌&#xff08;Google&#xff09;&#xff1a;脸书&#xff08;Facebook&#xff09;&#xff1a;亚马逊&#xff08;Amazon…

字符串函数内存函数(从零到一)【C语言】

长度不受限制的字符串函数&#xff1a;strcpy,strcat,strcmp 长度受限制的字符串函数&#xff1a;strncpy,strncat,strncmp strlen strlen函数是库函数中我们最常使用的函数&#xff0c;它可以求出字符串的长度(不包含‘\0’) 使用方法 通过前面对strlen函数的模拟实现我们知…

深度学习模型压缩方法:剪枝方法分类介绍

本文将介绍深度学习模型压缩方法中的剪枝,内容从剪枝简介、剪枝步骤、结构化剪枝与非结构化剪枝、静态剪枝与动态剪枝、硬剪枝与软剪枝等五个部分展开。 一、剪枝简介 在介绍剪枝之前,首先介绍过参数化这个概念,过参数化主要是指在训练阶段,在数学上需要进行大量的微分求解…