Java基础学习笔记(十五)—— Sream流

news2025/1/21 2:58:41

Sream流

  • 1 Stream流初体验
  • 2 Stream流概述
  • 3 生成Stream流
  • 4 中间操作方法
  • 5 终结操作方法
  • 6 收集操作方法
  • 7 Stream流案例

1 Stream流初体验

  • 案例需求
    • 创建一个集合,存储多个字符串元素
    • 把集合中所有以“张”开头的元素存储到一个新的集合
    • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
    • 遍历上一步得到的集合
  • 示例代码
public static void main(String[] args) {
	//集合的批量添加
	ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));
	//list.add()

	//遍历list1把以张开头的元素添加到list2中。
	ArrayList<String> list2 = new ArrayList<>();
	for (String s : list1) {
		if(s.startsWith("张")){
			list2.add(s);
		}
	}

	//遍历list2集合,把其中长度为3的元素,再添加到list3中。
	ArrayList<String> list3 = new ArrayList<>();
	for (String s : list2) {
		if(s.length() == 3){
			list3.add(s);
		}
	}
	for (String s : list3) {
		System.out.println(s);
	}

	System.out.println("=======================");
	
   //Stream流
	list1.stream().filter(s->s.startsWith("张"))
			.filter(s->s.length() == 3)
			.forEach(s-> System.out.println(s));
}

注意:List.of 是JDK9及以后的

2 Stream流概述

  • Stream流的好处
    • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义
    • Stream流把真正的函数式编程风格引入到Java中
    • 代码简洁
  • Stream流的三类方法
    • 获取Stream流
      • 创建一条流水线,并把数据放到流水线上准备进行操作
    • 中间方法
      • 流水线上的操作
      • 一次操作完毕之后,还可以继续进行其他操作
    • 终结方法
      • 一个Stream流只能有一个终结方法
      • 是流水线上的最后一个操作

3 生成Stream流

  • Collection体系集合
    • 使用默认方法stream()生成流, default Stream<E> stream()
  • Map体系集合
    • 把Map转成Set集合,间接的生成流
  • 数组
    • 通过Arrays中的静态方法stream生成流
  • 同种数据类型的多个数据
    • 通过Stream接口的静态方法of(T… values)生成流
public static void main(String[] args) {
	//单列集合
	//method1();

	//双列集合
	//method2();

	//数组
	//method3();

	//同种数据类型的多个数据
	//method4();
}

private static void method4() {
	Stream.of(1,2,3,4,5,6,7,8).forEach(s-> System.out.println(s));
}

private static void method3() {
	int [] arr = {1,2,3,4,5};
	Arrays.stream(arr).forEach(s-> System.out.println(s));
}

private static void method2() {
	HashMap<String,Integer> hm = new HashMap<>();
	hm.put("zhangsan",23);
	hm.put("lisi",24);
	hm.put("wangwu",25);
	hm.put("zhaoliu",26);
	hm.put("qianqi",27);

	//双列集合不能直接获取Stream流
	//1.keySet
	//先获取到所有的键
	//再把这个Set集合中所有的键放到Stream流中
	//hm.keySet().stream().forEach(s-> System.out.println(s));


	//2.entrySet
	//先获取到所有的键值对对象
	//再把这个Set集合中所有的键值对对象放到Stream流中
	hm.entrySet().stream().forEach(s-> System.out.println(s));
}

private static void method1() {
	ArrayList<String> list = new ArrayList<>();
	list.add("aaa");
	list.add("bbb");
	list.add("ccc");

//        Stream<String> stream = list.stream();
//        stream.forEach(s-> System.out.println(s));
	list.stream().forEach(s-> System.out.println(s));
}

4 中间操作方法

中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

在这里插入图片描述

filter方法

public static void main(String[] args) {
//        Stream<T> filter​(Predicate predicate):过滤
//                Predicate接口中的方法	boolean test​(T t):对给定的参数进行判断,返回一个布尔值

	ArrayList<String> list = new ArrayList<>();
	list.add("张三丰");
	list.add("张无忌");
	list.add("张翠山");
	list.add("王二麻子");
	list.add("张良");
	list.add("谢广坤");

	//filter方法获取流中的 每一个数据.
	//而test方法中的s,就依次表示流中的每一个数据.
	//我们只要在test方法中对s进行判断就可以了.
	//如果判断的结果为true,则当前的数据留下
	//如果判断的结果为false,则当前数据就不要.
//        list.stream().filter(
//                new Predicate<String>() {
//                    @Override
//                    public boolean test(String s) {
//                        boolean result = s.startsWith("张");
//                        return result;
//                    }
//                }
//        ).forEach(s-> System.out.println(s));


	//因为Predicate接口中只有一个抽象方法test
	//所以我们可以使用lambda表达式来简化
//        list.stream().filter(
//                (String s)->{
//                    boolean result = s.startsWith("张");
//                        return result;
//                }
//        ).forEach(s-> System.out.println(s));

	list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));
}

其他中间方法

public static void main(String[] args) {
	ArrayList<String> list = new ArrayList<>();
	list.add("张三丰");
	list.add("张无忌");
	list.add("张翠山");
	list.add("王二麻子");
	list.add("张良");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");


	//method1(list);
	//method2(list);
	//method3();
	//method4(list);


}

private static void method4(ArrayList<String> list) {
	//        Stream<T> distinct​():去除流中重复的元素。依赖(hashCode和equals方法)
	list.stream().distinct().forEach(s-> System.out.println(s));
}

private static void method3() {
	//static <T> Stream<T> concat​(Stream a, Stream b):合并a和b两个流为一个流
	ArrayList<String> list = new ArrayList<>();
	list.add("张三丰");
	list.add("张无忌");
	list.add("张翠山");
	list.add("王二麻子");
	list.add("张良");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");
	list.add("谢广坤");

	ArrayList<String> list2 = new ArrayList<>();
	list2.add("张三丰");
	list2.add("张无忌");
	list2.add("张翠山");
	list2.add("王二麻子");
	list2.add("张良");
	list2.add("谢广坤");


//        Stream<String> stream1 = list.stream();
//        Stream<String> stream2 = list2.stream();
//
//        Stream<String> stream3 = Stream.concat(stream1, stream2);
//        stream3.forEach(s-> System.out.println(s));

	Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.println(s));
}

private static void method2(ArrayList<String> list) {
	//        Stream<T> skip​(long n):跳过指定参数个数的数据
	list.stream().skip(2).forEach(s-> System.out.println(s));
}

private static void method1(ArrayList<String> list) {
	//        Stream<T> limit​(long maxSize):截取指定参数个数的数据
	list.stream().limit(2).forEach(s-> System.out.println(s));
}

5 终结操作方法

终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

在这里插入图片描述

public static void main(String[] args) {
	ArrayList<String> list = new ArrayList<>();
	list.add("张三丰");
	list.add("张无忌");
	list.add("张翠山");
	list.add("王二麻子");
	list.add("张良");
	list.add("谢广坤");

	//method1(list);


//        long count​():返回此流中的元素数
	long count = list.stream().count();
	System.out.println(count);


}

private static void method1(ArrayList<String> list) {
	//        void forEach​(Consumer action):对此流的每个元素执行操作
//                      Consumer接口中的方法	void accept​(T t):对给定的参数执行此操作
	//在forEach方法的底层,会循环获取到流中的每一个数据.
	//并循环调用accept方法,并把每一个数据传递给accept方法
	//s就依次表示了流中的每一个数据.
	//所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.
	list.stream().forEach(
			new Consumer<String>() {
				@Override
				public void accept(String s) {
					System.out.println(s);
				}
			}
	);

	System.out.println("====================");

	//lambda表达式的简化格式
	//是因为Consumer接口中,只有一个accept方法
	list.stream().forEach(
			(String s)->{
				System.out.println(s);
			}
	);
	System.out.println("====================");

	//lambda表达式还是可以进一步简化的.
	list.stream().forEach(s->System.out.println(s));
}

6 收集操作方法

对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中

常用方法

在这里插入图片描述

工具类Collectors提供了具体的收集方式

在这里插入图片描述

 /**
 * Stream流的收集方法
 * 练习:
 * 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
 * 将集合中的奇数删除,只保留偶数。
 * 遍历集合得到2,4,6,8,10。
 */
public static void main(String[] args) {
	ArrayList<Integer> list1 = new ArrayList<>();
	for (int i = 1; i <= 10; i++) {
		list1.add(i);
	}

	list1.add(10);
	list1.add(10);
	list1.add(10);
	list1.add(10);
	list1.add(10);

	//filter负责过滤数据的.
	//collect负责收集数据.
			//获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
	//Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
	List<Integer> list = list1.stream().filter(number -> number % 2 == 0)
			.collect(Collectors.toList());
	System.out.println(list);


	Set<Integer> set = list1.stream().filter(number -> number % 2 == 0)
			.collect(Collectors.toSet());
	System.out.println(set);
	
	// List和Set区别:Set有去重功能
}
/**
 * Stream流的收集方法
 *
 * 创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄
 * "zhangsan,23"
 * "lisi,24"
 * "wangwu,25"
 * 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
 */
 public static void main(String[] args) {
	ArrayList<String> list = new ArrayList<>();
	list.add("zhangsan,23");
	list.add("lisi,24");
	list.add("wangwu,25");

	Map<String, Integer> map = list.stream().filter(
			s -> {
				String[] split = s.split(",");
				int age = Integer.parseInt(split[1]);
				return age >= 24;
			}

	 //   collect方法只能获取到流中剩余的每一个数据.
	 //在底层不能创建容器,也不能把数据添加到容器当中

	 //Collectors.toMap 创建一个map集合并将数据添加到集合当中

	  // s 依次表示流中的每一个数据

	  //第一个lambda表达式就是如何获取到Map中的键
	  //第二个lambda表达式就是如何获取Map中的值
	).collect(Collectors.toMap(
			s -> s.split(",")[0],
			s -> Integer.parseInt(s.split(",")[1]) ));

	System.out.println(map);
}

注意:

  • Stream流只能操作流中的数据,而无法直接修改集合、数组等数据源中的数据

7 Stream流案例

案例需求

现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

  • 男演员只要名字为3个字的前三人
  • 女演员只要姓林的,并且不要第一个
  • 把过滤后的男演员姓名和女演员姓名合并到一起
  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

标准类演员类(Actor)已存在

测试类

public static void main(String[] args) {
	ArrayList<String>  manList = new ArrayList<>();
	manList.add("张国立");
	manList.add("张晋");
	manList.add("刘烨");
	manList.add("郑伊健");
	manList.add("徐峥");
	manList.add("王宝强");

	ArrayList<String>  womanList = new ArrayList<>();
	womanList.add("郑爽");
	womanList.add("杨紫");
	womanList.add("关晓彤");
	womanList.add("张天爱");
	womanList.add("杨幂");
	womanList.add("赵丽颖");

	//男演员只要名字为3个字的前两人
	Stream<String> stream1 = manList.stream().filter(name -> name.length() == 3).limit(2);

	//女演员只要姓杨的,并且不要第一个
	Stream<String> stream2 = womanList.stream().filter(name -> name.startsWith("杨")).skip(1);


	Stream.concat(stream1,stream2).forEach(name -> {
		Actor actor = new Actor(name);
		System.out.println(actor);
	});
}

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

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

相关文章

SpringCloud高级应用-2(Gateway-01)

Gateway介绍&#xff1a; Spring Cloud Gateway 是Spring Cloud团队的一个全新项目&#xff0c;基于Spring 5.0、SpringBoot2.0、Project Reactor 等技术开发的网关。旨在为微服务架构提供一种简单有效统一的API路由管理方式。 Spring Cloud Gateway 作为SpringCloud生态系统…

Acwing---1214.波动数列

波动数列1.题目2.基本思想3.代码实现1.题目 观察这个数列&#xff1a; 1 3 0 2 -1 1 -2 … 这个数列中后一项总是比前一项增加2或者减少3&#xff0c;且每一项都为整数。 栋栋对这种数列很好奇&#xff0c;他想知道长度为 n 和为 s 而且后一项总是比前一项增加 a 或者减少 …

Grafana配置sqlserver,展示数据

Grafana配置sqlserver&#xff0c;展示数据1. 连接数据源2. Visualization2.1 时间表达式2.2 Graph2.2.1 Example with metric column2.2.2 convert null values to be zero instead2.2.3 Using multiple columns3. AwakeningGrafana Document: https://grafana.com/docs/grafa…

java MultipartFile+vue+element 批量上传文件、图片,与普通数据同时提交保存才上传到后端

一.背景 文件上传项目可参考&#xff1a;点击预览 1.最简单也是最普遍的做法是form表单提交&#xff0c;其实前端提交到后端也是难以离开form表单提交&#xff0c; 一般有两种方式来处理文件、图片上传&#xff1a; 先上传&#xff0c;获取返回路径&#xff0c;再整个表单提…

PyTorch实现基本的线性回归

线性回归理论知识参考文章&#xff1a;线性回归 下面我们将从零开始实现整个线性回归方法&#xff0c; 包括数据集生成、模型、损失函数和小批量随机梯度下降优化器。 1.导入 %matplotlib inline import random import torch from d2l import torch as d2l2.生成数据集 我们…

js垃圾回收(引用计数算法、标记清除算法、v8垃圾回收机制、浏览器性能监控、任务管理器、内存分析、JSBench)

目录 垃圾 可达对象 GC算法&#xff08;垃圾回收机制&#xff09; 引用计数算法 优点 缺点 标记清除算法 优点 缺点 标记整理算法 优点 缺点 V8 V8垃圾回收 新生代对象回收 晋升条件 老生代对象回收 性能监控Performance 浏览器任务管理器 内存分析 ​编…

Apache Doris 系列: 基础篇-BitMap索引

1. 测试数据准备 本文使用SSB&#xff08;Star-Schema-Benchmark&#xff09;的测试数据&#xff0c;读者也可以自行准备测试数据 1.1 编译ssb-dbgen 数据生成工具 ## 拉取Apache Doris源代码 git clone https://github.com/apache/doris.git## 编译ssb-dbgen cd doris/tool…

计算机网络复习之应用层

统一资源定位系统&#xff08;uniform resource locator;URL&#xff09;是因特网的万维网服务程序上用于指定信息位置的表示方法。它最初是由蒂姆伯纳斯李发明用来作为万维网的地址。现在它已经被万维网联盟编制为互联网标准RFC1738。邮局协议&#xff08;Post Office Protoco…

TDemo 备注文本的二种存贮方式

TDemo 备注纯文本的二种存贮方式 数据库使用过程中&#xff0c;对于TDeme控件&#xff0c;对应数据库的分为nvarchar(n)类型字段。 一、通常使用二种格式的文本&#xff1a; &#xff08;1&#xff09;单纯文本 &#xff08;2&#xff09;带换行符的文本 这二种格式&#xff0c…

Pdf 转换成Word如何在线转换?职场公认好用软件推荐

Pdf 转换成Word如何在线转换&#xff1f;生活中很多时候我们需要接触大量的办公文件&#xff0c;特别是利用office的三种常见的文件格式编辑各类文件&#xff0c;最常见的便是Word文件操作。为了更方便我们进行文件传输&#xff0c;大部分情况下我们会把格式排版完好的Word文档…

UDS诊断系列介绍08-19服务

本文框架1. 系列介绍1.1 19服务概述1.2 DTC故障码定义1.3 DTC状态位2. 19服务常用子服务2.1 19 01服务2.2 19 02服务2.3 19 04服务2.4 19 06服务2.5 19 0A服务2.6 否定响应3. Autosar系列文章快速链接1. 系列介绍 UDS&#xff08;Unified Diagnostic Services&#xff09;协议…

Android 深入系统完全讲解(15)

4 权限相关的知识 1 安卓权限 上层 APK 权限获取方式&#xff0c;配置 AndroidManifest.xml&#xff0c;系统会对应的给 gid&#xff0c;在创建进程的时候就带下去&#xff0c;这样子就可以访问对应的设备。 而系统相关的&#xff0c;会限制必须是 uidsystem 这类&#xff0c…

一年融资三轮,一文读懂亿格云这家公司

数字办公时代&#xff0c;网络安全是企业经营的底线工作。如何构建一个安全、稳定、高效的网络安全体系&#xff0c;是企业谋求发展的基础条件之一。近年&#xff0c;倡导“永不信任&#xff0c;始终验证”的零信任网络安全服务理念开始兴起。而国内致力于基于零信任理念构建办…

MySQL 行级锁(行锁、临键锁、间隙锁)

行级锁 行级锁&#xff0c;每次操作锁住对应的行数据。锁定粒度最小&#xff0c;发生锁冲突的概率最低&#xff0c;并发度最高。应用在InnoDB存储引擎中。 InnoDB的数据是基于索引组织的&#xff0c;行锁是通过对索引上的索引项加锁来实现的&#xff0c;而不是对记录加的锁。 1…

类和对象(上)

文章目录引用autoNULL&nullptr&0类和对象类的实例化默认成员函数构造函数析构函数拷贝构造函数运算符的重载赋值运算符的重载拷贝构造次数编译器优化前置后置> < ! - -const成员operator>>&&operator<<再谈构造函数初始化列表初始化expli…

使用Hi3861开发环境搭建

安装ubuntu ​ 文件夹的位置尽量选一个空间比较大的 内存也尽量分配大一点&#xff0c;不要到红色区域就行 固定分配&#xff0c;如果给它100G空间&#xff0c;他就会把这100G空间全部使用掉&#xff0c;动态分配&#xff0c;即使你给他100G内存&#xff0c;但实际使用的空间…

【自学Docker】Docker入门

Docker入门 Docker简介 Docker 是 Docker.Lnc 公司开源的一个基于 LXC 技术之上搭建的 Container 容器引擎&#xff0c;Docker 源代码托管在 Github上&#xff0c;Docker 是基于 Go 语言开发的并遵从 Apache2.0 协议开源。 Docker 属于 Linux 容器的一种封装&#xff0c;提供…

(十九)包装类

前言: 在我们讨论其他变量类型之间的相互转换时&#xff0c;我们需要了解一下Java的包装类&#xff0c;所谓包装类&#xff0c;就是能够直接将简单类型的变量表示为一个类&#xff0c;在执行变量类型的相互转换时&#xff0c;我们会大量使用这些包装类。Java共有六个包装类&…

pandas数据结构

文章目录Series创建series对象Series对象的属性DataFrame创建DataFrame对象Python 在数据处理上独步天下&#xff1a;代码灵活、开发快速&#xff1b;尤其是 Python 的 Pandas 包&#xff0c;无论是在数据分析领域、还是大数据开发场景&#xff0c;都具有显著的优势。Series S…

CesiumLab实例模型切片 CesiumLab系列教程

先解释下实例模型&#xff0c;实例模型使用 GPU instance 技术来渲染的模型&#xff0c;通常用来绘制大量几何体一致&#xff0c;但是位置姿态不同的对象&#xff0c;比如说森林场景&#xff0c;大量路灯&#xff0c;井盖等&#xff0c;如下图&#xff1a; 1.输入文件 目前输入…