Java8新特性之——Stream API

文章目录

  • 一、简介
  • 二、操作分类
    • 创建流
      • 通过集合
      • 通过数组
      • 通过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.hqwc.cn/news/84712.html

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

相关文章

Jupyter Notebook 配置根目录

注&#xff1a;本文是在 Windows 10 上配置 Jupyter Notebook 打开的默认根目录&#xff0c;Linux 同。 步骤一&#xff1a;创建 Jupyter Notebook 配置文件 使用以下命令创建 Jupyter Notebook 配置文件&#xff08;如果尚未创建&#xff09;&#xff1a; jupyter notebook …

​LeetCode解法汇总5-正则表达式匹配​

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给你一棵…

单片机学习-蜂鸣器如何发出声音

硬件电路 软件编写 ①发出声音 #include "reg52.h" typedef unsigned int u16; // 重新定义 类型 typedef unsigned char u8; // 重新定义 类型sbit BEEP P2^5; //定义 P2第五个管教 为BEEP // 延时函数 void delay_time(u16 times) {while(times--); } vo…

【已解决】Docker启动MySQL容器失败:STATUS:‘ Exited (1) 2 minutes ago ‘,远程连接MySQL连不上问题

先查看正在运行的容器 # 查看正在运行的容器 docker ps # 查看所有的docker容器 docker ps -a 这个时候如果显示的是up状态&#xff0c;那就是启动成功了。 状态为exited&#xff0c;所以没有启动成功。 问题所在 好像是权限的问题 在docker run时额外加上参数 --privileged…

优维产品最佳实践第5期:什么是持续集成?

谈到到DevOps&#xff0c;持续交付流水线是绕不开的一个话题&#xff0c;相对于其他实践&#xff0c;通过流水线来实现快速高质量的交付价值是相对能快速见效的&#xff0c;特别对于开发测试人员&#xff0c;能够获得实实在在的收益。 本期EasyOps产品使用最佳实践&#xff0c…

Linux操作系统--克隆虚拟机

1.概述 我们在搭建大数据或者是集群的过程中,需要使用到许多配置相同或者相类似的环境。这一个时候就需要使用到克隆虚拟机的功能。 2.克隆虚拟机过程 (1).从现有虚拟机(关机状态)克隆出新虚拟机,右键选择管理=>克隆,如下所示 (2).直接点击下一步。如下所示 (3).选择…

21.2 CSS 三大特性与页面布局

1. 开发者工具修改样式 使用开发者工具修改样式, 操作步骤如下: * 1. 打开开发者工具: 在浏览器中右键点击页面, 然后选择检查或者使用快捷键(一般是 F12 或者 CtrlShiftI)来打开开发者工具.* 2. 打开样式编辑器: 在开发者工具中, 找到选项卡或面板, 一般是Elements或者Elemen…

职业发展和认证指导:提供网络安全从业者的职业规划建议,介绍各类认证考试和培训资源

章节一&#xff1a;引言 网络安全在今天的数字化世界中变得愈发重要&#xff0c;随之而来的是对网络安全专业人才的持续需求。作为一个追求在网络安全领域取得成功的从业者&#xff0c;职业规划和持续学习是不可或缺的一部分。本文将为你详细介绍如何规划你的网络安全职业发展…

ModaHub魔搭社区:WinPin经营大脑助手

产品介绍 智慧经营助手:企业专属的“数据工程师”“BI分析师” WinPlan决策系统 算力 阿里云 腾讯云 AWS亚马逊 框架 业务数据基座 WinPlan垂直大模型 模型 分析模型 预测模型 决策模型 应用 精准预测

html实现元素拖动替换

效果 实现 复制粘贴.html即可使用 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>拖动替换</title></head><style>.box {width: 500px;height: 500px;background: gainsboro;border-radius: 10px;}…

espidf vscode 安装出错ERROR_INVALID_PIP

解决链接&#xff1a;https://www.cnblogs.com/xiaohuzaixue/p/17558731.html 注意 不要使用win11的右键打开终端&#xff0c;在文件管理器上方输入cmd打开终端才有用。

opencv/C++ 人脸检测

前言 本文使用的测试资源说明&#xff1a; opencv版本&#xff1a;opencv 4.6.0 人脸检测算法 Haar特征分类器 Haar特征分类器是一个XML文件&#xff0c;描述了人体各个部位的Haar特征值。包括&#xff1a;人脸、眼睛、鼻子、嘴等。 opencv 4.6.0自带的Haar特征分类器&…