java集合类-操作集合

news2024/11/16 15:45:10

Collections(操作集合的工具类)
该工具类里提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了将集合对象1.设置为不可变、对集合对象实现同步控制等方法。自行看API即可。
2.有查找、替换集合元素的类方法。
有同步控制的方法,Collections类中提供了多个synchronizedXxx()方法,该方法可以将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题。
Java 中HashSet 、 TreeSet 、ArrayList、ArrayDeque、LinkedList、HashMap和TreeMap都是线程不安全的。如果有多个线程访问它们,而且有超过一个的线程试图修改它们,则存在线程安全的问题。Collections提供了多个类方法可以把它们包装成线程同步的集合。
3.有设置不可变集合的方法。Java 9新增的不可变集合,增加了一个功能,以前假如要创建一个包含6个元素的Set集合,程序需要先创建Set集合,然后调用6次add()方法向Set集合中添加元素。Java 9对此进行了简化,程序直接调用Set、List、Map的of()方法即可创建包含N个元素的不可变集合,这样一行代码就可创建包含N个元素的集合。不可变意味着程序不能向集合中添加元素,也不能从集合中删除元素。
使用集合元素创建不可变集合,其中Set、List比较简单,程序只要为它们的of()方法传入N个集合元素即可创建Set、List集合。创建不可变的Map集合有两个方法: 使用of()方法时只要依次传入多个key-value对即可;还可使用ofEntries()方法,该方法可接受多个Entry对象,因此程序显式使用Map.entry()方法来创建Map.Entry对象。

Collection接口和Iterator接口
Java 11增强了Collection接口和Iterator接口,Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可操作Set集合,也可操作List和Queue集合。集合类就像容器,现实生活中容器的功能,无非就是添加对象、删除对象、清空容器、判断容器是否为空等,集合类就为这些功能提供了对应的方法。Collection接口里定义了如下操作集合元素的方法,自行查看API文档;
1.boolean add(Object o):该方法用于向集合里添加一个元素。如果集合对象被添加操作改变了,则返回true。
2.boolean addAll(Collection c):该方法把集合c里的所有元素添加到指定集合里。如果集合对象被添加操作改变了,则返回true。
3.void clear():清除集合里的所有元素,将集合长度变为0。
4.boolean contains(Object o):返回集合里是否包含指定元素。
5.boolean containsAll(Collection c):返回集合里是否包含集合c里的所有元素。
6.boolean isEmpty():返回集合是否为空。当集合长度为0时返回true,否则返回false。
7.Iterator iterator():返回一个Iterator对象,用于遍历集合里的元素。
8.boolean remove(Object o):删除集合中的指定元素o,当集合中包含了一个或多个元素o时,该方法只删除第一个符合条件的元素,该方法将返回true。
9.boolean removeAll(Collection c):从集合中删除集合c里包 含的所有元素(相当于用调用该方法的集合减集合c),如果删除了一个或一个以上的元素,则该方法返回true。
10.boolean retainAll(Collection c):从集合中删除集合c里不包含的元素(相当于把调用该方法的集合变成该集合和集合c的 交集),如果该操作改变了调用该方法的集合,则该方法返回true。
11.int size():该方法返回集合里元素的个数。
12.Object[] toArray():该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素。
涉及到泛型:
Java 11为Collection新增了一个toArray(IntFunction)方法,使用该方法的主要目的就是利用泛型。对于传统的toArray()方法而言,不管Collection本身是否使用泛型, toArray() 的 返回值总是Object[];但新增的toArray(IntFunction)方法不同,当Collection使用泛型时,toArray(IntFunction)可以返回特定类型的数组。toArray(IntFunction)方法的特点:
由于编译器推断strColl的类型为List(带泛型),因此该方法的返回值就是String[]类型。需要额外说明的是,由于使用该方法的主要目的就是利用泛型,因此toArray(IntFunction)方法参数通常就是它要返回的数组类型后面加双冒号和new(构造器引用)。

使用Lambda表达式遍历集合
Iterable接口是Collection接口的父接口,Java 8为Iterable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,因此Collection集合也可直接调用该方法。
当程序调用Iterable的forEach(Consumer action)遍历集合元素时,程序会依次将集合元素传给Consumer的accept(T t)方法(该接口中唯一的抽象方法)。正因为Consumer是函数式接口,因此可以使用Lambda表达式来遍历集合元素。
在这里插入图片描述
上面程序中调用了Iterable的forEach()默认方法来遍历集合元素,传给该方法的参数是一个Lambda表达式,该Lambda表达式的目标类型是Consumer。forEach()方法会自动将集合元素逐个地传给Lambda表达式的形参,这样Lambda表达式的代码体即可遍历到集合元素了。

使用Iterator遍历集合元素
Iterator接口是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果是先Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList,后面会再涉及。
Iterator接口也是Java集合框架的成员,但它与Collection系列、Map系列的集合不一样:Collection系列集合、Map系列集合主要用于盛装其他对象,而Iterator则主要用于遍历(即迭代访问)Collection集合中的元素,Iterator对象也被称为迭代器。Iterator仅用于遍历集合,Iterator本 身并不提供盛装对象的能力。如果需要创建Iterator对象,则必须有 一个被迭代的集合。没有集合的Iterator仿佛无本之木,没有存在的价值。
Iterator接口隐藏了各种Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。Iterator接口里定义了如下4个方法。
1.boolean hasNext():如果被迭代的集合元素还没有被遍历完,则返回true。
2.Object next():返回集合里的下一个元素。
3.void remove():删除集合里上一次next方法返回的元素。
4.void forEachRemaining(Consumer action),这是Java 8为Iterator新增的默认方法,该
方法可使用Lambda表达式来遍历集合元素。
注意一个结论:
当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对集合元素本身没有任何影响。
当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只有通过Iterator的remove()方法删除上一次next()方法返回的集合元素才可以,否则将引发java.util.Concurrent ModificationException异常。
在这里插入图片描述
红框内代码位于Iterator迭代块内,也就是在Iterator迭代Collection集合过程中修改了Collection集合,所以程序将在运行时引发异常。
Iterator迭代器采用的是快速失败(fail-fast)机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中的其他线程修改),程序立即引发ConcurrentModificationException异常,而不是显示修改后的结果,这样可以避免共享资源而引发的潜在问题。

使用Lambda表达式遍历Iterator???垃圾,其实就是参数可以是lambda。。。
Java 8 为Iterator新增了一个forEachRemaining(Consumer action)方法,该方法所需的Consumer参数同样也是函数式接口。当程序调用Iterator的forEachRemaining(Consumer action)遍历集合元素时,程序会依次将集合元素传给Consumer的accept(T t)方法(该接口中唯一的抽象方法)。

foreach循环遍历集合元素:
使用foreach循环遍历集合元素,上面不是说过?不一样,forEach循环就是。。。。for循环,前面说的是forEach()方法。。。。。。
除可使用Iterator接口迭代访问Collection集合里的元素之外, 使用Java 5提供的foreach循环迭代访问集合元素更加便捷。

使用Predicate操作集合
Java8为Collection集合新增了一个removeIf(Predicate filter)方法,该方法将会批量删除符合filter条件的所有元素。该方法需要一个Predicate(谓词)对象作为参数,Predicate也是函数式接口,因此可使用Lambda表达式作为参数。
在这里插入图片描述
上面程序中粗体字代码调用了Collection集合的removeIf()方法批量删除集合中符合条件的元素,程序传入一个Lambda表达式作为过滤条件:所有长度小于10的字符串元素都会被删除。使用Predicate可以充分简化集合的运算,假设依然有上面程序所示的books集合,如果程序有如下三个统计需求:
1.统计书名中出现“疯狂”字符串的图书数量。
2.统计书名中出现“Java”字符串的图书数量。
3.统计书名长度大于10的图书数量。
此处只是一个假设,实际上还可能有更多的统计需求。如果采用传统的编程方式来完成这些需求,则需要执行三次循环,但采用Predicate只需要一个方法即可。如下程示范了这种用法。

在这里插入图片描述
上面程序先定义了一个calAll()方法,该方法将会使用Predicate判断每个集合元素是否符合特定条件,该条件将通过Predicate参数动态传入。从上面程序中三行粗体字代码可以看到,程序传入了三个Lambda表达式(其目标类型都是Predicate),这样calAll()方法就会统计满足Predicate条件的图书。

Stream操作集合(流)
Java 8新增了Stream、IntStream、LongStream、DoubleStream等流式API,这些API代表多个支持串行和并行聚集操作的元素。上面4 个接口中,Stream是一个通用的流接口,而IntStream、LongStream、DoubleStream则代表元素类型为int、long、double的流。
Java8为每个流式API都提供了对应的Builder,例如Stream.Builder 、 IntStream.Builder 、 LongStream.Builder 、DoubleStream.Builder,开发者可以通过这些Builder来创建对应的
流。独立使用Stream的步骤如下:
①使用Stream或XxxStream的builder()类方法创建该Stream对应的Builder。
②重复调用Builder的add()方法向该流中添加多个元素。
③调用Builder的build()方法获取对应的Stream。
④调用Stream的聚集方法。
在上面4个步骤中,第4步可以根据具体需求来调用不同的方法,Stream提供了大量的聚集方法供用户调用,具体可参考Stream或XxxStream的API文档。对于大部分聚集方法而言,每个Stream只能执行一次。
在这里插入图片描述
创建了一个IntStream然后分别调用IntStream的聚集方法执行操作,这样即可获取该流的相关信息。注意:上面粗体字代码每次只能执行一行,因此需要把其他粗体字代码
注释掉。流过去就没了。。。。。
Stream提供了大量的方法进行聚集操作,这些方法既可以是“中间的”(intermediate),也可以是“末端的”(terminal)。
1.中间方法:中间操作允许流保持打开状态,并允许直接调用后续方法。上面程序中的map()方法就是中间方法。中间方法的返回值是另外一个流。下面简单介绍一下Stream常用的中间方法。
1.1filter(Predicate predicate):过滤Stream中所有不符合predicate的元素。
1.2.mapToXxx(ToXxxFunction mapper):使用ToXxxFunction对流中的元素执行一对一的转换,该方法返回的新流中包含了ToXxxFunction转换生成的所有元素。
1.3.peek(Consumer action):依次对每个元素执行一些操作,该方法返回的流与原有流包含相同的元素。该方法主要用于调试。
1.4.distinct():该方法用于排序流中所有重复的元素(判断元素重复的标准是使用equals()比较返回true)。这是一个有状态的方法。
1.5.sorted():该方法用于保证流中的元素在后续的访问中处于有序状态。这是一个有状态的方法。
1.6.limit(long maxSize):该方法用于保证对该流的后续访问中最大允许访问的元素个数。这是一个有状态的、短路方法。

2.末端方法:
末端方法是对流的最终操作。当对某个Stream执行末端方法后,该流将会被“消耗”且不再可用。上面程序中的sum()、count()、average()等方法都是末端方法。下面简单介绍一下Stream常用的末端方法。
2.1forEach(Consumer action):遍历流中所有元素,对每个元素执行action。
2.2toArray():将流中所有元素转换为一个数组。
2.3reduce():该方法有三个重载的版本,都用于通过某种操作来合并流中的元素。
2.4min():返回流中所有元素的最小值。
2.5max():返回流中所有元素的最大值。
2.6count():返回流中所有元素的数量。
2.7anyMatch(Predicate predicate):判断流中是否至少包含一个元素符合Predicate条件。
2.8allMatch(Predicate predicate):判断流中是否每个元素都符合Predicate条件。
2.9noneMatch(Predicate predicate):判断流中是否所有元素都不符合Predicate条件。
2.10findFirst():返回流中的第一个元素。
2.11findAny():返回流中的任意一个元素。
除此之外,Java 8允许使用流式API来操作集合,Collection接口提供了一个stream()默认方法,该方法可返回该集合对应的流,接下来即可通过流式API来操作集合元素。由于Stream可以对集合元素进行整体的聚集操作,因此Stream极大地丰富了集合的功能。
例如之前介绍的示例程序,该程序需要额外定义一个calAll()方法来遍历集合元素,然后依次对每个集合元素进行判断——这太麻烦了。如果使用Stream,即可直接对集合中所有元素进行批量操作。下面使用Stream来改写这个程序。
在这里插入图片描述
从上面程序中粗体字代码可以看出,程序只要调用Collection的stream()方法即可返回该集合对应的Stream,接下来就可通过Stream提供的方法对所有集合元素进行处理,这样大大地简化了集合编程的代码,这也是Stream编程带来的优势。
最后的代码就是先调用Collection对象的stream()方法将集合转换为Stream对象,然后调用Stream对象的mapToInt()方法将其转换为IntStream,其中这个mapToInt()方法就是一 个中间方法,因此程序可继续调用IntStream的forEach()方法来遍历流中的元素。

除此之外,关于流的方法还有如下两个特征。
1.有状态的方法:这种方法会给流增加一些新的属性,比如元素的唯一性、元素的最大数量、保证元素以排序的方式被处理等。有状态的方法往往需要更大的性能开销。
2.短路方法:短路方法可以尽早结束对流的操作,不必检查所有的元素。

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

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

相关文章

使用 Python 深度学习方法对电影评论进行情绪预测

情感分析是一种自然语言处理问题,可以理解文本并预测潜在意图。 在本文中,你将了解如何使用 Keras 深度学习库将电影评论的情绪预测为正面或负面。 看完这篇文章,你会知道: 关于自然语言处理的 IMDB 情感分析问题以及如何在 Ke…

核心表结构

核心表结构目录概述需求:参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive. happy for hardess to solve denp…

Android重新签名APK

前提已经配置好了Java环境。在要签名的apk文件目录路径位置,输入cmd,打开命令窗口。在命令窗口中输入jarsigner,有相应的提示。然后输入重新签名指令如下:jarsigner -verbose -keystore E:\tmc\keystore\androidsign.jks -signedj…

51单片机学习笔记-10IIC总线

10 I2C总线 [toc] 注:笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。 10.1 AT24C02和I2C介绍 10.1.1 存储器介绍 图10-1 存储器分类 一般来说,RAM读写速度极快,但掉电丢失;而…

InfluxDB OSS v2.6.0安装使用小结(ubuntu Linux)

1 InfluxDB简介 InfluxDB是一款用Go语言编写的开源分布式时序、事件和指标数据库。 官网:https://www.influxdata.com 1.1 特色 InfluxDB的主要特色 1)无结构(无模式):可以是任意数量的列 2)可拓展的 3&…

学习云原生的阅读书单

以下是我从豆瓣阅读上找到的书单 《云原生服务网格lstio》 《云原生操作系统Kubernetes》 《OpenShift云原生架构:原理与实践》

[oeasy]python0066_控制序列_光标位置设置_ESC_逃逸字符_CSI

光标位置 回忆上次内容 上次讲了 三引号的输出三引号中 回车和引号 都会 被原样输出\ 还是需要从 \\转义 黑暗森林 快被摸排清了 还有哪个 转义序列 没 研究过吗?🤔 \e是 干什么的?🤔 回忆转义 转义转义 转化含义 \反斜杠(…

CnOpenData劳务外包企业工商注册基本信息数据

一、数据简介 随着我国社会主义市场经济的发展,劳务市场中的用工方式也朝着多样化方向演变,劳务外包正是现代化人力资源管理和企业生产实际结合的一种独特的新模式。 在劳务外包过程中,企业将人事管理的部分或者全部工作外包给一个专门的服务…

Hadoop 复习 ---- chapter01【大数据概念】

Hadoop 复习 ---- chapter01【大数据概念】1. 什么是大数据大数据的简介从IT过渡到DT2. Hadoop生态系统工具HADOOPHBASEHIVESTORMZooKeeperSqoopMAHOUT1. 什么是大数据 大数据的简介 指“无法由现有软件工具进行提取、存储、搜索、共享、分析和处理的庞大而复杂的数据集”。 通…

【软件测试】某城商行手机银行授权漏洞分析黑客攻击,测试优化手段......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 问题描述 据报道&am…

【FreeRTOS】详细讲解FreeRTOS的软件定时器及通过示例讲述其用法

软件定时器 所谓定时器,也就可以类比生活中人们常用的闹钟,可以单次响铃提醒,也可以间隔固定时间响铃提醒;与FreeRTOS定时器不同的是周期不同,FreeRTOS的周期更加短,一般使用毫秒(ms)、秒(s)。   软件定时…

Python的数字类型、布尔类型和运算优先级

文章目录1.数字类型1.1分类1.2整数1.3浮点数1.4复数2.数字运算符2.1运算符表格2.2 运算符 //3.divmod()函数4.abs()函数4. int(),float() 和 complex() 函数5.pow()函数和运算符 **6.布尔类型6.…

NB-IoT的低功耗特性原理解说

什么是NB-IoT NB-IoT的中文名叫窄带蜂窝物联网(Narrow Band Internet of Things),NB-IoT网络是基于4G网络演进过来的,所以它在上行和下行的复用技术上还是沿用了4G的OFDMA和SC-FDMA。NB-IoT有三大特性:速率低,成本低,…

电脑风扇声音大怎么办?具体原因以及解决措施,快速解决

​很多小伙伴使用台式电脑,使用的时间长了,电脑机箱里的风扇就会发出一些噪音,很影响小伙伴的整体使用体验。电脑风扇声音大怎么办?具体的原因以及解决措施有哪些?下面就跟着小编一起来看看吧。 一、电脑风扇声音大的原…

数据挖掘,计算机网络、操作系统刷题笔记39

数据挖掘,计算机网络、操作系统刷题笔记39 2022找工作是学历、能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,orac…

Kibana最新版8.6.1安装教程

Kibana 让您能够自由地选择如何呈现自己的数据。不过借助 Kibana 的交互式可视化,您可以先从一个问题出发,看看能够从中发现些什么。查看完整的 Kibana 功能列表https://www.elastic.co/cn/kibana/featuresKibana的下载地址:https://www.elas…

有状态/无状态认证

文章目录一、什么是有状态认证?二、什么是无状态认证?(token)三、无状态分布式认证解决方案一、什么是有状态认证? 有状态认证,即服务端需要记录每次会话的客户端信息,从而识别客户端身份&#…

几种最小二乘法及python代码:ELS、TLS、RLS

1.ARMAX模型 下面各章节,我就是使用上面公式的符号,其中y是输出,u是输入,e是噪声。有m个输出y,r个输入u。 进一步精简为: YPθE 其中:Y为要预测的部分,P为已知数据(包…

k8s添加node节点和master节点

一.准备1.基本概述版本:kubelet:v1.20.4docker: 20.10.23资源:cpu:8mem:16kernel:3.10.0-1160.71.1.el7.x86_64镜像仓库地址:registry.cn-hangzhou.aliyuncs.com/google_containers/…

大部分人都容易焦虑,那么应该如何对待焦虑呢?

新年伊始,告别喜庆欢乐的春节,大家应该已经投入到正常的工作当中去了。面对节后的开工,难免都会有点焦虑,因为大多数人还沉浸在春节喜悦的回忆当中,回忆都是美好的,因为回忆中是带有感情的,美好…