Java基础——Stream类

news2024/12/24 3:38:39

文章目录

  • 1 概述
  • 2 获取Stream对象
  • 3 常用API
  • 4 收集Stream流
  • 5 总结

1 概述

Stream类用于简化集合和数组操作的API。
Stream类提供了很多可以简化集合操作的api,比如过滤元素
示例如下:
假如一个List集合中存储着字符串,从这些字符串中找到以“1”开头并长度为3的字符串加入一个新的List集合中。

public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();

    list.add("123");
    list.add("145435");
    list.add("145");
    list.add("234");
    list.add("5435");
    list.add("189");

    ArrayList<String> newList = new ArrayList<>();
    for (String s : list) {
        if (s.startsWith("1") && s.length() == 3) {
            newList.add(s);
        }
    }
    System.out.println(newList);
}

使用stream可以简化上面的写法

public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();

    list.add("123");
    list.add("145435");
    list.add("145");
    list.add("234");
    list.add("5435");
    list.add("189");

    ArrayList<String> newList = new ArrayList<>();

    list.stream().filter(s -> s.startsWith("1")).filter(s -> s.length() == 3).forEach(s -> newList.add(s));
    System.out.println(newList);
}

Stream流其中的一些接口返回的还是Stream对象,可以支持链式编程。
通常使用步骤可以分为:

  • 获取集合和数组的Stream流

  • 放置元素

  • 使用Stream流的api方便操作元素
    Stream当中的方法可以分为:

  • 获取Stream流

  • 中间方法:返回的还是Stream对象

  • 终结方法:无返回,代表Stream使用结束

2 获取Stream对象

//集合
Collection<String> list = new ArrayList<>();
Stream<String> s = list.stream();
//Map
Map<String, Integer> map = new HashMap<>();
Stream<String> keyStream = map.keySet().stream();
Stream<Integer> valueStream = map.values().stream();
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
//数组
String[] strs = {"4324", "243324"};
Stream<String> strStream = Arrays.stream(strs);
Stream<String> strStream1 = Stream.of(strs);

Collection接口中提供了stream方法用于返回stream流

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

是一个默认方法。
Map中可以返回key、value和entry类型的stream流
数组返回stream流借助于Arrays工具类,其中Stream中的静态方法of也是借助于Arrays工具类返回Stream流

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

3 常用API

先创建一个List集合

ArrayList<String> list = new ArrayList<>();

list.add("123");
list.add("145435");
list.add("145");
list.add("234");
list.add("5435");
list.add("189");
  • 过滤和遍历
//Stream<T> filter(Predicate<? super T> predicate);
//void forEach(Consumer<? super T> action);
list.stream().filter(s -> s.startsWith("1")).forEach(s -> System.out.println(s));

filter返回一个stream对象,forEach返回空,用于遍历元素。
输出:

123
145435
145
189
  • 统计元素个数
//long count();
long size = list.stream().filter(s -> s.startsWith("1")).count();
System.out.println(size);

输出

4
  • 取前几个元素或跳过前几个元素
//Stream<T> limit(long maxSize);
list.stream().filter(s -> s.startsWith("1")).limit(2).forEach(System.out::println);
//Stream<T> skip(long n);
list.stream().filter(s -> s.startsWith("1")).skip(2).forEach(System.out::println);

输出

123
145435
145
189

这两个方法的参数都只能取大于等于0的值,否则会报异常。limit当值大于size时,取全部元素,skip当值大于size时,不返回任何元素。

  • 加工元素
//<R> Stream<R> map(Function<? super T, ? extends R> mapper);
list.stream().map(s -> "map: " + s).forEach(System.out::println);

输出:

map: 123
map: 145435
map: 145
map: 234
map: 5435
map: 189

入参是一个函数式接口Function,重写apply方法,用于操作修改元素。
还可以构建对象

list.stream().map(s -> new Number(s)).forEach(System.out::println);

Number是一个类,包含了一个有参构造,可以通过map构造一个Number对象的stream流。

  • 合并流
Stream<String> s1 = list.stream().filter(s -> s.startsWith("1"));
Stream<String> s2 = Stream.of("213","231");
Stream<Object> s3 = Stream.concat(s1, s2);
s3.forEach(System.out::println);

concat是Stream接口中的一个静态方法。

public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
    Objects.requireNonNull(a);
    Objects.requireNonNull(b);

    @SuppressWarnings("unchecked")
    Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
            (Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
    Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
    return stream.onClose(Streams.composedClose(a, b));
}

接收的泛型必须是两个的公共父类
输出:

123
145435
145
189
213
231
  • 去除重复
list.stream().distinct().forEach(System.out::println);

去除重复的元素,依赖于hashCode方法和equals方法

4 收集Stream流

将Stream操作后的数据转回集合和数组中去

//收集到List集合中
Stream<String> s1 = list.stream().filter(s -> s.startsWith("1"));
List<String> newList = s1.collect(Collectors.toList());
//List<String> newList1 = s1.toList(); //也是stream被收集过了,不能再使用
System.out.println(newList);
//收集到Set集合中
Set<String> newSet = s1.collect(Collectors.toSet()); //1
System.out.println(newSet);

注释1处报错
在这里插入图片描述
流只能收集一次,收集一次之后,就不能再使用了。

Stream<String> s1 = list.stream().filter(s -> s.startsWith("1"));
Object[] strs = s1.toArray();
System.out.println(Arrays.toString(strs));

转换成数组,就直接使用toArray方法,返回的是一个Object数组,因为Stream流中可以引入其他类型的元素
如果能够确定Stream中的元素都是同一种类型,则可以直接通过toArray的一个api去操作

String[] strs = s1.toArray(String[]::new);

提供一个构造,构造传入的是特定类型数组长度,数组长度会通过toArray传入。

5 总结

  • Stream流用于简化数组和集合的操作
  • 其中常用方法有filter过滤集合元素、forEach遍历集合元素、map加工集合元素、count统计元素个数、concat拼接Stream流、distinct去重等
  • Stream操作集合和数组元素之后需要转回集合或数组
  • 通过提供的toArraytoListcollect方法来完成收集转化

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

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

相关文章

Java反射 -- 详细介绍 (框架核心)

反射 是 Java框架 的核心 &#xff0c;无论是Tomcat、SpringMVC、Spring IOC、Spring AOP、动态代理 &#xff0c;都使用到了 反射 反射的作用简单讲就是 无需 new 对象&#xff0c;就可以动态获取到一个类的全部信息&#xff0c;包括 属性、方法&#xff0c;构造器&#xff0…

iOS--属性关键字

定义 chat&#xff1a; 在iOS开发中&#xff0c;属性关键字是用于声明类的属性&#xff08;实例变量&#xff09;的修饰符。属性关键字可以影响属性的访问权限、内存管理和生成相关的getter和setter方法。 属性关键字有哪些&#xff1f; 分类属性关键字原子性atomic、nonato…

dpdpdp

这里写目录标题 139. 单词拆分322. 零钱兑换300. 最长递增子序列120. 三角形最小路径和64. 最小路径和63. 不同路径 II5. 最长回文子串&#xff08;回文dp&#xff09;⭐97. 交错字符串⭐&#xff08;抽象成路径问题&#xff09;221. 最大正方形⭐ 139. 单词拆分 class Soluti…

实用便捷!一站式BI系统推荐

在企业数字化转型过程中&#xff0c;BI系统可以建立业务、数据的双驱引擎&#xff0c;形成业务、数据的互补作用&#xff0c;通过建立数字化技术架构&#xff0c;明确企业的战略定位和业务目标&#xff0c;从而支撑实现这个目标。而一站式BI系统&#xff0c;则是指可以轻松从数…

使用Soft-RoCE实践RDMA

RDMA介绍 RDMA&#xff08; Remote Direct Memory Access &#xff09;意为远程直接地址访问&#xff0c;通过RDMA&#xff0c;本端节点可以“直接”访问远端节点的内存。所谓直接&#xff0c;指的是可以像访问本地内存一样&#xff0c;绕过传统以太网复杂的TCP/IP网络协议栈读…

Github 上有没有优秀的Java 项目推荐?

前言 下面是我精心整理的GitHub上关于Java的高Star的项目&#xff0c;可以自己选择去练手喔&#xff0c;希望对你有帮助~ 我们直接进入正题——> 1、 JavaGuide Star&#xff1a;135k JavaGuide指的是一份完整的Java学习指南或学习资料&#xff0c;它提供了Java编程语言…

AcWing4118. 狗和猫

输入样例1&#xff1a; 3 6 10 4 0 CCDCDD 4 1 2 0 CCCC 4 2 1 0 DCCD输出样例1&#xff1a; Case #1: YES Case #2: YES Case #3: NO样例1解释 在 Case 1 中&#xff0c;一共有 1010 份狗粮和 44 份猫粮。 前两只动物是猫&#xff0c;喂食它们后&#xff0c;还剩下 22 份猫粮…

数据结构之BinaryTree(二叉树)的实现

BinaryTree要实现的方法 总结 remove不在BinNode里&#xff0c;而是BinTree里 递归的两种写法 从上往下&#xff1a;同一对象的递归&#xff08;参数多一个&#xff0c;判空用一句话&#xff09;&#xff0c;子对象的递归&#xff08;参数void&#xff0c;判空用两句话&#…

算法分析和设计简答题

算法分析和设计简答题 1.1分治法的算法思想&#xff08;重点&#xff09; 1.2动态规划的算法思想&#xff08;重点&#xff09; 1.3贪心算法的算法思想 1.4回溯算法的算法思想 1.5分支限界法的算法思想 1.6时间复杂度的定义(最好/一般/坏)&#xff0c;有什么意思 1.7渐进记号…

【Git】分支合并冲突产生与解决

文章学习自&#xff1a;麦兜搞IT&#xff0c;如有侵权&#xff0c;告知删除 文章目录 前言1 Fast Forword 合并1.1 核心原理1.2 举个栗子1.3 经验之谈 2 three way merge2.1 核心原理2.2 举个栗子&#xff08;不带冲突&#xff09;2.3 带冲突的three way merge 3 变基rebase3.…

Windows上配置Python环境变量

Python配置环境变量 &#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; Python下载官网&#xff1…

GB28181设备接入端如何播放语音广播数据?

技术背景 语音广播功能是GB28181设备接入端非常重要的功能属性&#xff0c;语音广播让终端和平台之间&#xff0c;有了实时双向互动&#xff0c;可以满足执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、…

Docker介绍以及实战教程

Docker简介 Docker为什么出现 从事软件开发的朋友&#xff0c;可能经常会碰到以下场景&#xff1a;运维&#xff1a;你这程序有Bug啊&#xff0c;怎么跑不起来啊&#xff01;开发&#xff1a;我机子上能跑啊&#xff0c;你会不会用啊究其原因还是开发环境与生产环境不同造成的…

基于linux下的高并发服务器开发(第二章)- 2.18 内存映射(2)

1.如果对mmap的返回值(ptr)做操作(ptr), munmap是否能够成功? void * ptr mmap(...);ptr; 可以对其进行操作munmap(ptr, len); // 错误,要保存地址 2.如果open时O_RDONLY, mmap时prot参数指定PROT_READ | PROT_WRITE会怎样? 错误&#xff0c;返回MAP_FAILEDopen()函数中的…

cpolar+calibre搭建自己的kindle书库

cpolarcalibre搭建自己的kindle书库 在我们身边众多的便携电子设备中&#xff0c;Kindle无疑是最为矛盾的设备之一&#xff0c;很多人在买它时都想读书破万卷&#xff0c;可是到最后Kindle的归宿都是盖泡面。尽管如此&#xff0c;当亚马逊不讲武德&#xff0c;打算将Kindle真正…

FPGA中RAM的结构理解

FPGA中RAM的结构理解 看代码的过程中对RAM的结构不是很理解&#xff0c;搞脑子一片浆糊&#xff0c;反复推算&#xff0c;好不容易理清了思路&#xff0c;记录下来&#xff0c;防止忘记。开辟的RAM总容量为128bytes&#xff0c;数据的位宽为32位&#xff08;即一个单元有32bit…

CodeForces:Madoka and Underground Competitions

经过观察&#xff0c;发现只要延小区域 右上-左下 的对角线填满X即可&#xff0c;那么就是可以总结为满足(i j) % k (r c) % k #include <bits/stdc.h> using namespace std; int t; void solve(){int n, k, r, c;cin >> n >> k >> r >> c…

团队如何选择合适的Git分支策略?

现代软件开发过程中要实现高效的团队协作&#xff0c;需要使用代码分支管理工具实现代码的共享、追溯、回滚及维护等功能。目前流行的代码管理工具&#xff0c;包括CVS&#xff0c;SVN&#xff0c;Git&#xff0c;Mercurial等。 相比CVS和SVN的集中管理&#xff0c;Git具有非常…

【stable diffusion】保姆级入门课程03-Stable diffusion(SD)图生图-涂鸦(绘图)的用法

目录 0.本章素材 1.涂鸦有什么用 2.涂鸦的使用场景是什么 3.操作面板 4.提示词与涂鸦 5.涂鸦与重绘幅度 6.涂鸦的其他用法(自由创作) 7.课后训练 0.本章素材 Realistic Vision V3.0模型(真实系模型)百度网盘链接&#xff1a;https://pan.baidu.com/s/1HkSKW2t4L6wMg…