Java8新特性之——Stream API

news2024/12/24 20:14:16

文章目录

  • 一、简介
  • 二、操作分类
    • 创建流
      • 通过集合
      • 通过数组
      • 通过Stream的of()方法
    • 中间操作
      • 无状态
      • 有状态
    • 结束操作
      • 非短路操作
      • 短路操作

一、简介

JDK 8 引入了 Stream API,它是用于处理集合数据的功能强大的库。Stream API 提供了一种更为简洁、灵活和函数式的方式来进行集合的操作和处理。

Stream API 有三大特性:

  • 不存储数据:Stream API 并不会在内存中存储数据,它仅仅是对源数据进行操作和处理的管道,当我们对一个集合或数组创建流时,流只是作为一种处理方式存在,并没有实际保存数据。
  • 不改变源数据:Stream API 的操作不会改变原始数据源中的元素,所有的中间操作(如过滤、映射、排序)都会产生一个新的流,而不是直接修改原始数据。这种特性确保了数据的不可变性。
  • 延时执行:Stream API 使用了延迟执行的概念。它并不会立即执行流的操作,而是等到需要结果时才进行计算。这样可以避免不必要的计算,提高效率并节省资源。只有在终端操作(如聚合、收集、计数)被调用时,流才会进行实际的计算。

二、操作分类

在使用 Stream API 进行集合操作时,一般会遵循以下步骤:

  1. 创建流:通过集合或数组创建一个流
  2. 中间操作:对流进行一系列的中间操作,例如过滤、映射、排序等。这些操作可以按照需求进行链式调用
  3. 结束操作:中间操作只是一种标记,只有结束操作才会触发实际计算

其中中间操作又分为,无状态和有状态,结束操作又分为短路操作和非短路操作

image-20230825170946157

创建流

通过集合

可以使用 Collection 接口中的 stream() 方法或者 parallelStream() 方法来创建一个流

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();

通过数组

可以使用 Arrays 类中的静态方法 stream() 来创建一个数组的流

String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

通过Stream的of()方法

可以使用 Stream 类中的静态方法 of() 来根据指定的元素创建一个流

Stream<String> stream = Stream.of("a", "b", "c");

中间操作

无状态

元素的处理不受前一个元素影响

  • filter(过滤):接收一个 Predicate 参数,根据 Predicate 的判断结果决定是否保留流中的元素, true 留下,false 丢弃
  • map、mapToInt、mapToLong、mapToDouble(转换):map 方法接收一个 Function 参数,将流中的每个元素通过该函数进行转换,mapToInt、mapToLong、mapToDouble 和 map 差不多,只是强制指定了返回值必须是 int、long、double 类型
  • flatMap、flatMapToInt、flatMapToLong、flatMapToDouble(合并):将一个或多个流合并成一个新流,flatMapToInt、flatMapToLong、flatMapToDouble 和 f latMap 差不多,只是返回的是对应的 IntStream、LongStream、DoubleStream 流
  • peek(监测):接受一个Consumer 函数作为参数,该函数会在流的每个元素被处理时被调用。它可以用于在处理流的过程中观察每个元素的值,而不会改变流的内容
//filter
public static void main(String[] args) {
    String[] str = {"a", "b", "c"};
    Stream.of(str).filter(t -> t.equals("a")).forEach(System.out::println);
    //输出
    //a
}

//map、mapToInt、mapToLong、mapToDouble
public static void main(String[] args) {
    String[] str = {"a", "b", "c"};
    Stream.of(str).map(t -> t.toUpperCase()).forEach(System.out::println);
    Stream.of(str).mapToInt(t -> t.hashCode()).forEach(System.out::println);
    //输出
    //A
    //B
    //C
    //97
    //98
    //99
}

//flatMap、flatMapToInt、flatMapToLong、flatMapToDouble
public static void main(String[] args) {
    List<String> a = new ArrayList<>();
    a.add("a");
    a.add("b");
    List<String> b = new ArrayList<>();
    b.add("c");
    b.add("d");
    Stream.of(a, b).flatMap(u -> u.stream()).forEach(System.out::println);
    //输出
    //a
    //b
    //c
    //d
}

//peek
public static void main(String[] args) {
    String[] str = {"a", "b", "c"};
    Stream.of(str).peek(t -> System.out.println("this is " + t)).collect(Collectors.toList());
    //输出
    //this is a
    //this is b
    //this is c
}

有状态

必须等所有元素处理完毕之后才知道最终的结果

  • distinct(去重):去除重复的元素
  • sorted(排序):不传参数,会按照自然排序,也可以传一个比较器参数,会根据比较器定义的顺序排序
  • limit(限制):截取前n个元素
  • skip(跳过):跳过n个元素,返回之后的元素
//distinct
public static void main(String[] args) {
    String[] str = {"a", "a", "b", "b", "c"};
    Stream.of(str).distinct().forEach(System.out::println);
    //输出
    //a
    //b
    //c
}

//sorted
public static void main(String[] args) {
    String[] str = {"banana", "apple", "pineapple", "pear", "watermelon"};
    Stream.of(str).sorted().forEach(System.out::println);
    System.out.println("---------------");
    Stream.of(str).sorted(Comparator.comparing(String::length)).forEach(System.out::println);
    //输出
    //apple
    //banana
    //pear
    //pineapple
    //watermelon
    //---------------
    //pear
    //apple
    //banana
    //pineapple
    //watermelon
}

//limit
public static void main(String[] args) {
    String[] str = {"a", "b", "c", "d", "e"};
    Stream.of(str).limit(2).forEach(System.out::println);
    //输出
    //a
    //b
}

//skip
public static void main(String[] args) {
    String[] str = {"a", "b", "c", "d", "e"};
    Stream.of(str).skip(2).forEach(System.out::println);
    //输出
    //c
    //d
    //e
}

结束操作

非短路操作

需要处理完所有元素

  • forEach(循环):循环操作Stream中数据
  • forEachOrdered(排序循环):按照流的遭遇顺序来处理元素,在并行流中使用
  • toArray(转数组):不传参数的话,返回的是对象数组,也可以接收一个 IntFunction<A[]> generator 参数来指定返回数据的类型
  • reduce(聚合):聚合操作,一般用来做统计
  • collect(收集):将元素收集到一个集合或其他数据结构里
  • min(最小值):根据传入的比较器,找到最小的元素
  • max(最大值):根据传入的比较器,找到最大的元素
  • count(总数量):计数,统计元素数量
//forEach
public static void main(String[] args) {
    String[] str = {"a", "b", "c"};
    Stream.of(str).forEach(System.out::println);
    //输出
    //a
    //b
    //c
}

//toArray
public static void main(String[] args) {
    String[] str = {"1", "2", "3"};
    Object[] objectArray = Stream.of(str).toArray();
    String[] strArray = Stream.of(str).toArray(String[]::new);
}

//reduce
public static void main(String[] args) {
    Integer[] array = {1, 2, 3, 4, 5};
    Optional<Integer> optional = Stream.of(array).reduce((x, y) -> x + y);
    optional.ifPresent(System.out::println);
    //输出
    //15
}

//collect
public static void main(String[] args) {
    Integer[] array = {1, 2, 3, 4, 5};
    List<Integer> list = Stream.of(array).collect(Collectors.toList());
    System.out.println(list);
    //输出
    //[1, 2, 3, 4, 5]
}

//min
public static void main(String[] args) {
    Integer[] array = {1, 2, 3, 4, 5};
    Optional<Integer> min = Stream.of(array).min(Comparator.comparing(Integer::intValue));
    min.ifPresent(System.out::println);
    //输出
    //1
}

//max
public static void main(String[] args) {
    Integer[] array = {1, 2, 3, 4, 5};
    Optional<Integer> max = Stream.of(array).max(Comparator.comparing(Integer::intValue));
    max.ifPresent(System.out::println);
    //输出
    //5
}

//count
public static void main(String[] args) {
    String[] str = {"a", "b", "c"};
    long count = Stream.of(str).count();
    System.out.println(count);
    //输出
    //3
}

短路操作

一旦满足或不满足条件,就结束计算,不用处理完所有元素

  • anyMatch:只要有一个符合条件就返回 true
  • allMatch:所有都符合条件返回 true
  • noneMatch:所有数据都不符合条件返回true
  • findFirst:获取第一个元素
  • findAny:获取任一元素,一般用于并行流
//anyMatch
public static void main(String[] args) {
    String[] str = {"banana", "apple", "pineapple", "pear", "watermelon"};
    boolean b = Stream.of(str).anyMatch(t -> t.length() == 4);
    boolean b2 = Stream.of(str).anyMatch(t -> t.length() == 3);
    System.out.println(b);
    System.out.println(b2);
    //输出
    //true
    //false
}

//allMatch
public static void main(String[] args) {
    String[] str = {"banana", "apple", "pineapple", "pear", "watermelon"};
    boolean b = Stream.of(str).allMatch(t -> t.length() >= 4);
    boolean b2 = Stream.of(str).allMatch(t -> t.length() >= 5);
    System.out.println(b);
    System.out.println(b2);
    //输出
    //true
    //false
}

//noneMatch
public static void main(String[] args) {
    String[] str = {"banana", "apple", "pineapple", "pear", "watermelon"};
    boolean b = Stream.of(str).noneMatch(t -> t.length() >= 4);
    boolean b2 = Stream.of(str).noneMatch(t -> t.length() <= 3);
    System.out.println(b);
    System.out.println(b2);
    //输出
    //false
    //true
}

//findFirst
public static void main(String[] args) {
    String[] str = {"banana", "apple", "pineapple", "pear", "watermelon"};
    Optional<String> first = Stream.of(str).findFirst();
    first.ifPresent(System.out::println);
    //输出
    //banana
}

//findAny
public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    numbers.parallelStream()
        .filter(n -> n % 2 == 0)
        .findAny().ifPresent(System.out::println);
    //输出
    //2 or 4
}

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

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

相关文章

Google Play商店优化排名因素之应用截图与视频

屏幕截图是影响转化率的最重要的视觉效果之一。大多数人只需查看应用程序屏幕截图&#xff0c;就会决定是否尝试去下载我们的应用程序。 1、在Google Play商店中&#xff0c;搜索结果页面根据我们搜索的关键词有不同的样式。 展示应用程序中最好的部分&#xff0c;添加一些文字…

电商微信小程序项目介绍

微信公众号&#xff1a;大数据高性能计算 ** 小程序&#xff1a;张氏大闸蟹 ** 最近准备写一写非保持练手的内容&#xff0c;我目前在国内某互联网公司上班&#xff0c;主要做一些分布式图计算、图平台、高性能计算相关的工作&#xff0c;准备后续更一些大家可能以后工作需…

Vue3 [Day11]

Vue3的优势 create-vue搭建Vue3项目 node -v npm init vuelatest npm installVue3项目目录和关键文件 Vetur插件是Vue2的 Volarr插件是Vue3的 main.js import ./assets/main.css// new Vue() 创建一个应用实例 > createApp() // createRouter() createStore() // 将创建实…

HTML学习笔记02

HTML笔记02 页面结构分析 元素名描述header标题头部区域的内容&#xff08;用于页面或页面中的一块区域&#xff09;footer标记脚部区域的内容&#xff08;用于整个页面或页面的一块区域&#xff09;sectionWeb页面中的一块独立区域article独立的文章内容aside相关内容或应用…

systemverilog之program与module的区别

为避免仿真和设计竞争问题(race condition)&#xff0c;systemverilog中引入了program的概念。 在Verilog中&#xff0c;调度如下图所示&#xff1a; 从图中可以看出&#xff0c;阻塞赋值与非阻塞赋值的调度是不一样的&#xff0c;其中#0的阻塞延时赋值则处在中间的调度区域。…

图像后期处理操作

1. 引言 最近&#xff0c;在闲暇之余&#xff0c;拍摄了一些昆虫的照片。我发现在手持拍摄昆虫时&#xff0c;几乎不可能拍出一次排除完美的照片。通常我们对照明的控制有限&#xff0c;对取景的控制有限&#xff08;由于焦距和所有的树枝和树叶&#xff09;&#xff0c;以及对…

2000-2021年上市公司在建工程环保投资(原始数据+计算代码)

2000-2021年上市公司在建工程环保投资&#xff08;原始数据计算代码&#xff09; 1、时间&#xff1a;2000-2021年 2、来源&#xff1a;整理自上市公司年报 3、指标&#xff1a;证券代码、公司名称、年份、在建工程环保投资、期末总资产在建工程环保投资/期末总资产 4、参考…

Centos7 安装llama-cpp-python失败

报错信息如下&#xff1a; 解决步骤&#xff1a; yum remove gcc yum remove gdb yum install scl-utils yum install centos-release-scl yum list all --enablerepocentos-sclo-rh | grep "devtoolset" yum install -y devtoolset-11-toolchain vi ~/.bash_p…

基于Java+SpringBoot+Vue前后端分离党员教育和管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

win11+vmware17+centos7.9环境搭建

温故知新 &#x1f4da;第一章 前言&#x1f4d7;背景&#x1f4d7;目标&#x1f4d7;总体方向 &#x1f4da;第二章 安装部署环境&#x1f4d7;安装VMware Workstation 17 Pro软件&#x1f4d7;安装CentOS-7虚拟机&#x1f4d5;镜像下载地址&#x1f4d5;创建虚拟机&#x1f4…

【目标检测】理论篇(2)YOLOv3网络构架及其代码实现

网络构架图&#xff1a; 代码实现&#xff1a; import math from collections import OrderedDictimport torch.nn as nn#---------------------------------------------------------------------# # 残差结构 # 利用一个1x1卷积下降通道数&#xff0c;然后利用一个3x3卷…

数据分析--统计学知识

描述型统计 描述统计 1.集中趋势 &#xff1a;众数、平均数、分位数 2.离散趋势&#xff1a; 极值&#xff08;max&#xff09;、极差&#xff08;max-min&#xff09;、平均差、方差、标准差、分位差 3.分布&#xff1a;峰泰、偏度 推理型统计 概率分布&#xff1a;离散型…

eBPF程序注入到内核中的流程,现在就带你研究(上)

” 系列目录 1. 疑惑 2. vfsstat_bpf__open 2.1 bpf_object__open_skeleton 2.2 bpf_object__open_mem/bpf_object_open 2.3 OPTS_VALID检查参数合法性 2.4 bpf_object__new新建bpf_object对象 2.5 bpf_object__elf_init初始化elf文件 2.6 bpf_object__elf_collect收集各个段落…

攻防世界-embarrass

原题 解题思路 搜索flag&#xff0c;结果搜不到。 换到kali里看。

STM32f103入门(2)流水灯蜂鸣器

流水灯 /* #define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ #define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ #define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ #de…

pnpm安装包管理工具

pnpm安装包管理工具 pnpm代表performant npm&#xff08;高性能的npm&#xff09;&#xff0c;同npm和Yarn&#xff0c;都属于Javascript包管理安装工具&#xff0c;它较npm和Yarn在性能上得到很大提升&#xff0c;被称为快速的&#xff0c;节省磁盘空间的包管理工具。 pnpm…

QT6编译的文件分布情况

工程文件和编译文件位置分布 工程文件是自己建立的源文件位置&#xff0c;而同等级的位置在工程构建时会重新生成一个编译后的文件夹&#xff0c;里面包含了可执行的exe文件。而这个文件夹的内容也是QT ide运行时读取的文件&#xff0c;但这个文件的内容在IDE中如果不重新构建…

darknet yolo make报错,缺少instance-segmenter.o的规则

文章目录 darknet yolo make报错&#xff0c;缺少instance-segmenter.o的规则报错原因解决办法新问题解决办法 补充g编译选项Makefile编译规则 darknet yolo make报错&#xff0c;缺少instance-segmenter.o的规则 报错原因 Makefile没有识别到对于instance-segmenter.o的编译…

论文解读:高质量物体追踪

本文介绍了HQTrack&#xff0c;一种新的高质量视频物体追踪框架。HQTrack结合了视频多目标分割器&#xff08;VMOS&#xff09;和蒙版细化器&#xff08;MR&#xff09;&#xff0c;可追踪视频初始帧中指定的物体&#xff0c;并对追踪结果进行细化&#xff0c;以获得更高的准确…

【C++】4、Preprocessor 预处理:条件编译、源文件包含、宏替换、重定义行号、错误信息、编译器预留指令

文章目录 一、概述二、格式2.1 条件编译2.2 源文件包含2.3 宏替换2.3.1 语法2.3.2 C标准内置的预定义宏 2.4 重定义行号和文件名2.5 错误信息2.6 编译器预留指令 三、应用场景 C的 Build 可分为4个步骤&#xff1a;预处理、编译、汇编、链接。 预处理就是本文要详细说的宏替换…