Java 8 Stream 流用法及语法

Java 8 Stream 流用法

1.简介

Stream流 最全的用法
Stream 能用来干什么?用来处理集合,通过 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询,Stream API 提供了一种高效且易于使用的处理数据的方式

为什么用Java 8 Stream ?因为 操作简单
为什么操作简单?因为 Lambda 表达式,它极大的提高了编程效率和程序可读性
怎么操作流? 首先你的有个数据源(数组、集合),操作会产生新的流对象,原来的流对象不会改变
流用法有结束操作,这种代码不是你写了一个方法就执行一个方法,而是最后触发结束操作的时候才统一执行的,collect、foreach 方法就是一种结束方法,详情看代码及结果参考 2.映射map、flatMap用法 部分


2.具体用法

2.1 创建流
 // 集合创建流List<String> list = new ArrayList<>();// 获取一个顺序流Stream<String> listStream = list.stream();// 获取一个并行流Stream<String> parallelListStream = list.parallelStream();// 数组创建流Integer[] nums = new Integer[] { 1, 2, 3, 4, 5 };Stream<Integer> arrStream = Arrays.stream(nums);arrStream.forEach(System.out::println);// 1 2 3 4 5// 静态方法of创建流Stream<Integer> ofStream = Stream.of(1, 2, 3, 4, 5);ofStream.forEach(System.out::println);// 1 2 3 4 5// 静态方法iterate 创建流Stream<Integer> iterateStream = Stream.iterate(1, (x) -> x + 10).limit(4);iterateStream.forEach(System.out::println); // 1 11 21 31// 静态方法generate 创建流Stream<Double> generateStream = Stream.generate(Math::random).limit(2);generateStream.forEach(System.out::println);
2.2 操作流
1.过滤
  • filter:过滤流中的某些元素(可以做一些基本的判空、替换、判断逻辑操作)
  • limit(n):获取n个元素,结果获取几个元素
  • skip(n):跳过n元素,配合limit(n)可实现分页
  • distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
        //filter 判空Stream<Integer> notNullStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream<Integer> notNullStream = notNullStreamObj.filter(i -> (null != i));notNullStream.forEach(System.out::println);//1 2 4 5 6 7 2//filter 逻辑判断Stream<Integer> logicStreamObj = Stream.of(1, 2, null, 4, 5, 6, 7, null, 2);Stream<Integer> logicStream = logicStreamObj.filter(i -> (i != null && i > 5));logicStream.forEach(System.out::println); // 6 7//filter 替换Stream<String> strStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream<String> strStream = strStreamObj.filter(str -> (null != str && str.contains("a")));strStream.forEach(System.out::println); // aa ab ac//skip 跳过Stream<String> skipStreamObj = Stream.of("aa", "ab", null, "ac", "bd", "ee");Stream<String> skipStream = skipStreamObj.skip(2);skipStream.forEach(System.out::println); // null ac bd ee//distinct 去重Stream<String> disStreamObj = Stream.of("aa", "ab", null, "ac", "aa", "ab", null, "ee");Stream<String> disStream = disStreamObj.distinct();disStream.forEach(System.out::println); // aa ab null ac ee
2.映射
  • map:接收一个函数作为参数,该函数会被应用到每个元素上,映射成一个新的元素。
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
  • peek:这个操作很骚,类似map只不过map 是Func函数,提供返回值,而peer是取出元素,Consumer表达式设值,我个人觉得没啥区别呢,官方文档提示:该方法主要用于调试,做一些消耗这个对象但不修改它的东西,没啥事不要用
很想问一下 这俩map、flatMap 区别 ,细品,你细品,你细细品

map是将每个元素 映射成一个新元素,除非你过滤了,否则不会改变元素个数
flatMap是将原流中的每个值都变成另一个流,然后把流合并串起来,必须有返回值,拼装成新的流

        //map 把包含a的元素,替换成| 注意,注意, 元素还是一个整体,对每个元素Stream<String> mapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> mapStream = mapStreamObj.map(str -> str.replaceAll(",", "|"));mapStream.forEach(System.out::println); // a|b|c a|e|f h|i|j//flatMap 可以把元素 切分后,再按照新元素组成新的字符串Stream<String> flatMapStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> flatMapStream = flatMapStreamObj.flatMap(str -> {String[] arr = str.split(",");Stream<String> result = Arrays.stream(arr);return result;});flatMapStream.forEach(System.out::println); //a b c d e f g h iSystem.out.println("1===========");Stream<String> peekStreamObj = Stream.of("a,b,c", "a,e,f", "g,h,i");Stream<String> peekStream = peekStreamObj.peek(e -> System.out.println("Filtered value: " + e)).map(String::toUpperCase).peek(e -> System.out.println("Mapped value: " + e));System.out.println("2=========== peek代码结束,但是日志没打印");Set<String> stringSet = peekStream.collect(Collectors.toSet());System.out.println("3=========== collect结束操作,代码日志打印");stringSet.forEach(System.out::println);

map执行结果

//看下执行结果,说明 collect才是结束操作,代码结束,但是并不是真正结束
1===========
2=========== peek代码结束,但是日志没打印
Filtered value: a,b,c
Mapped value: A,B,C
Filtered value: a,e,f
Mapped value: A,E,F
Filtered value: g,h,i
Mapped value: G,H,I
3=========== collect结束操作,代码日志打印
A,B,C
A,E,F
G,H,I
3.排序
  • sorted():自然排序,流中元素需实现Comparable接口
  • sorted(Comparator com):定制排序,自定义Comparator排序器

先构建一个User类

 public static class User {private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}

然后 看下sort用法

//按字母排序Stream<String> sortStreamObj = Stream.of("a,e,f", "a,d,c", "a,b,i");Stream<String> sortStream = sortStreamObj.sorted();sortStream.forEach(System.out::println); //abi adc aefUser u1 = new User("bb", 1);User u2 = new User("aa", 2);User u3 = new User("cc", 3);User u4 = new User("aa", 4);Set<User> userSet = Sets.newHashSet(u1, u2, u3, u4);Stream<User> userStream = userSet.stream().sorted((obj1, obj2) -> {if (obj1.getName().equals(obj2.getName())) {//name相等 按agereturn obj1.getAge() - obj2.getAge();}return obj1.getName().compareTo(obj2.getName());});userStream.forEach(System.out::println);// u2 u4 u1 u3

sort 执行结果

a,b,i
a,d,c
a,e,f
User{name='aa', age=2}
User{name='aa', age=4}
User{name='bb', age=1}
User{name='cc', age=3}
4.流匹配
  • allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
  • noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
  • anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
  • findFirst:返回流中第一个元素
  • findAny:返回流中的任意元素
  • count:返回流中元素的总个数
  • max:返回流中元素最大值
  • min:返回流中元素最小值
        List<Integer> numLists = Arrays.asList(3, 4, 5, 6, 10);// 全部匹配 - trueboolean allMatch1 = numLists.stream().allMatch(e -> e > 2); //trueSystem.out.println("allMatch1:" + allMatch1);// 全部匹配 - trueboolean allMatch2 = numLists.stream().allMatch(e -> e > 5); //falseSystem.out.println("allMatch2:" + allMatch2);// 全部都不符合 - trueboolean noneMatch = numLists.stream().noneMatch(e -> e > 20); //trueSystem.out.println("noneMatch:" + noneMatch);// 任一元素符合 - trueboolean anyMatch = numLists.stream().anyMatch(e -> e > 4);  //trueSystem.out.println("anyMatch:" + anyMatch);//返回第一个Integer findFirst = numLists.stream().findFirst().get(); //3System.out.println("findFirst:" + findFirst);//返回任一个Integer findAny = numLists.stream().findAny().get(); System.out.println("findAny:" + findAny);//返回 countlong count = numLists.stream().count(); //5System.out.println("count:" + count);//返回maxInteger max = numLists.stream().max(Integer::compareTo).get(); //10System.out.println("max:" + max);//返回minInteger min = numLists.stream().min(Integer::compareTo).get();//3System.out.println("min:" + min);

匹配执行结果

allMatch1:true
allMatch2:false
noneMatch:true
anyMatch:true
findFirst:3
findAny:3
count:5
max:10
min:3
5.组合操作
  • Reduce 就是组合操作
  • Reduce(BinaryOperator accumulator) 没有起始值,按照运算规则进行运算操作
    解释:第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素,按照函数进行操作;
    第二次执行时,第一个参数为第一次函数执行操作的结果,第二个参数为流中的第三个元素;往下依次类推,返回Optinal 通过get()方法获取结果
  • Reduce(T identity, BinaryOperator accumulator)含有初始值,第二个是第一个的变形,跟第一个方法对比,不同的是此次这个会接受一个identity参数,用来指定Stream循环的初始值。如果Stream为空,就直接返回该值,特殊:该方法不会返回 Optional
Optional sumResult = Stream.of(1, 2, 3, 4).reduce((sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("-----——---");return sum;});System.out.println("========sumResult: " + sumResult.get());Integer sumDefineResult = Stream.of(1, 2, 3, 4).reduce(100, (sum, item) -> {System.out.println("sum : " + sum);sum += item;System.out.println("item: " + item);System.out.println("sum+ : " + sum);System.out.println("---——-----");return sum;});System.out.println("========sumDefineResult: " + sumDefineResult);

reduce 执行结果

//下面是执行结果
//查看执行结果
sum : 1
item: 2
sum+ : 3
-----——---
sum : 3
item: 3
sum+ : 6
-----——---
sum : 6
item: 4
sum+ : 10
-----——---
========sumResult: 10
sum : 100
item: 1
sum+ : 101
---——-----
sum : 101
item: 2
sum+ : 103
---——-----
sum : 103
item: 3
sum+ : 106
---——-----
sum : 106
item: 4
sum+ : 110
---——-----
========sumDefineResult: 110
6. 收集转换操作

这是个最最最最最基本的操作,10个流操作 9个都会使用到当前操作

  • collect(Collectors.toList()) 转换List
  • collect(Collectors.toSet()) 转换Set
  • Collectors.toMap(key, value) 转换Map ,如果key重复,!!!报错
  • Collectors.joining() join进行拼接
  • Collectors.groupingBy(key) 以Key为map的 key分组
  • Collectors.partitioningBy(规则) 以规则分区 比如 >5 ,map key为true,false
        User s1 = new User("aa", 1);User s2 = new User("bb", 2);User s3 = new User("cc", 3);User s4 = new User("dd", 2);List<User> list = Arrays.asList(s1, s2, s3, s4);//转换listList<Integer> ageList = list.stream().map(User::getAge).collect(Collectors.toList()); // [1, 2, 3]System.out.println(ageList.toString());//转成setSet<Integer> ageSet = list.stream().map(User::getAge).collect(Collectors.toSet()); // [1, 2, 3]System.out.println(ageSet);//转成map,注:key不能相同,否则报错Map<String, Integer> userMap = list.stream().collect(Collectors.toMap(User::getName, User::getAge)); // {cc=10, bb=20, aa=10}System.out.println(userMap);//字符串分隔符连接String joinName = list.stream().map(User::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)System.out.println(joinName);//分组Map<Integer, List<User>> ageMap = list.stream().collect(Collectors.groupingBy(User::getAge));System.out.println(ageMap);//多重分组,先根据类型分再根据年龄分Map<Integer, Map<Integer, List<User>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(User::getAge, Collectors.groupingBy(User::getAge)));System.out.println(typeAgeMap);//分区//分成两部分,true 一部分age大于2岁, false 一部分age小于等于2岁Map<Boolean, List<User>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 2));System.out.println(partMap);

collect 执行结果

[1, 2, 3, 2]
[1, 2, 3]
{dd=2, cc=3, bb=2, aa=1}
(aa,bb,cc,dd)
{1=[User{name='aa', age=1}], 2=[User{name='bb', age=2}, User{name='dd', age=2}], 3=[User{name='cc', age=3}]}
{1={1=[User{name='aa', age=1}]}, 2={2=[User{name='bb', age=2}, User{name='dd', age=2}]}, 3={3=[User{name='cc', age=3}]}}
{false=[User{name='aa', age=1}, User{name='bb', age=2}, User{name='dd', age=2}], true=[User{name='cc', age=3}]}

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

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

相关文章

wapper打成linux服务,Wrapper配置详解及高级应用(转)

转自&#xff1a;http://286.iteye.com/blog/1921414将一个简单的程度如HelloWorld 的应用包装秤Wrapper 服务并不复杂&#xff0c;甚至可以认为非常简单。但是实际项目应用过程中我们的程序一般较庞大&#xff0c;运行环境也较复杂。通过Wrapper 配置文件的分析与配置进一步了…

Java8 Stream 流机制和 Lambda 表达式

一、Stream 流介绍与使用场景 Stream 流介绍 java8 中的stream 与InputStream和OutputStream是完全不同的概念, stream 是用于对集合迭代器的增强&#xff0c;使之完成能够完成更高效的聚合操作&#xff08;过滤、排序、统计分组&#xff09;或者大批量数据操作。stream 与 L…

嵌入式linux安装qt,树莓派上安装qt

在树莓派上安装了官方的raspbian系统。为了在能在上面开发程序&#xff0c;在系统上安装了qt4 。参考链接http://qt-project.org/wiki/apt-get_Qt4_on_the_Raspberry_Piapt-getFirstly I got the development tools needed by Qt Creator in the hope it would be less heavy f…

linux guide编译器,GUIDE编译器-GUIDE编程工具-GUIDE编译器下载 v1.0.2官方版-完美下载...

GUIDE编译器是款跨平台的开发环境编程工具&#xff0c;支持C/C 和 Pascal三种语言&#xff0c;具有跨平台、操作简单、跨编程语言和单文件编译调试等特点&#xff0c;为用户提供单文件编译、调试和运行的环境。GUIDE编译器特色1、跨平台&#xff1a; GUIDE 可在 linux 平台和 w…

MySQL事务隔离级别和实现原理

经常提到数据库的事务&#xff0c;那你知道数据库还有事务隔离的说法吗&#xff0c;事务隔离还有隔离级别&#xff0c;那什么是事务隔离&#xff0c;隔离级别又是什么呢&#xff1f;本文就帮大家梳理一下。 MySQL 事务 本文所说的 MySQL 事务都是指在 InnoDB 引擎下&#xff0…

Linux如何清除last信息,linux清除last、lastb和history记录

清除登录系统成功的记录&#xff0c;也就是last命令看到的记录[rootlocalhost root]# echo ""> /var/log/wtmp 此文件默认打开时乱码的&#xff0c;里面可以看到ip等等信息[rootlocalhost root]# echo "">/var/log/wtmp[rootlocalhost root]# last此…

超级全面的MySQL优化面试解析

推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4. Mybatis内容聚合 5. 多线程内容聚合 超级全面的MySQL优化面试解析 本文概要 概述 为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上随着应用程序的运行&#…

mysql linux导入csv主键,MySQL导入csv文件内容到Table及数据库的自增主键设置

写在前面目的是测试将csv文件内容导入到表中, 同时记录一下自增主键的设置.测试采用MySQL8.0.新建表customer_info如下, 未设置主键.修改上表, 添加主键id, 并设置为自增.ALTER TABLE customer_info ADD COLUMN id INT AUTO_INCREMENT NOT NULL PRIMARY KEY;导入步骤1.为了模拟…

mysql 优化方法有哪些?

MySQL索引 MySQL支持诸多存储引擎&#xff0c;而各种存储引擎对索引的支持也各不相同&#xff0c;因此MySQL数据库支持多种索引类型&#xff0c;如BTree索引&#xff0c;哈希索引&#xff0c;全文索引等等。为了避免混乱&#xff0c;本文将只关注于BTree索引&#xff0c;因为这…

linux shell脚本判断文件行数,判断文件是否存在的shell脚本代码

实现代码一、#!/bin/sh# 判断文件是否存在# lilSzqFnk&#xff1a;www.jb51.net# date&#xff1a;2013/2/28myPath"/var/log/httpd/"myFile"/var /log/httpd/access.log"# 这里的-x 参数判断$myPath是否存在并且是否具有可执行权限if [ ! -x "$myPat…

Linux下多功能编辑器,Linux下的编辑器——vi大全

xp 交换两个字符位置ddp 上下两行调换J 上下两行合并dG 删除所有行d$ 从当前位置删除到行尾y$ 从当前位置复制到行尾, 如果要粘贴到其他地方 p就可以了:ab string strings例如 ":ab usa United States of America" ,当你在文见里插入 usa 时United States of America…

Mysql中几种插入效率的实例对比

前言 最近因为工作的需要&#xff0c;要在Mysql里插入大量的数据大约1000w&#xff0c;目测会比较耗时。所以现在就像测试一下到底用什么插入数据的方法比较快捷高效。 下面就针对每一种方法分别测试不同数据量下的插入效率。 测试数据库的基本与操作如下&#xff1a; mysq…

linux第三方模块参数,nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)...

nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)&#xff0c;安装Nginx和HttpAccessKeyModule模块(参考LNMP环境搭建&#xff1a;第一步&#xff1a;在/usr/local/src/下下载模块压缩包&#xff1a;wget http://wiki.nginx.org/images/5…

Java基础面试题与答案

八种基本数据类型以及包装类 八种基本数据类型默认值&#xff1f;大小&#xff1f;范围区间&#xff1f;包装类的缓存区间&#xff1f; 序号类型名称默认值大小最小值最大值包装类缓冲区间1booleanfalse1B0(false)1(true)Boolean无2byte(byte)01B-128127Byte-128 ~ 1273char‘…

学习vim的linux游戏,PacVim:一个学习 vim 命令的命令行游戏 | Linux 中国

作者 | Sk 译者 | geekpi &#x1f48e; &#x1f48e; 共计翻译&#xff1a;735 篇 贡献时间&#xff1a;1691 天你好&#xff0c;Vim用户&#xff01;今天&#xff0c;我偶然发现了一个很酷的程序来提高 Vim 的使用技巧。Vim 是编写和编辑代码的绝佳编辑器。然而&#x…

Java多线程面试题与答案

线程 线程与进程的区别是什么&#xff1f; 进程指的是应用程序在操作系统中执行的副本&#xff08;系统分配资源的最小单位&#xff09;&#xff0c;线程是程序执行的最小单位&#xff1b;进程使用独立的数据空间&#xff0c;而线程共享进程的数据空间。 线程状态图 多线程会…

用linux集成电路版图设计,集成电路版图设计报告.doc

集成电路版图设计报告集成电路版图设计实验报告班 级&#xff1a;微电子1302班学 号&#xff1a;1306090226姓 名&#xff1a;李根日 期&#xff1a;2016年1月10日一&#xff1a;实验目的&#xff1a;熟悉IC设计软件Cadence Layout Editor的使用方法&#xff0c;掌握集成电路原…

JVM面试题与答案

JVM内存布局 JVM在内存布局上可以分为哪些区域&#xff1f; 堆&#xff08;线程共享&#xff09;&#xff1a;GC的主要回收地&#xff0c;包含几乎所有的实例对象、字符串常量池&#xff1b;元空间&#xff08;线程共享&#xff09;&#xff1a;在本地内存分配&#xff0c;包…

md0和md1linux软raid,软RAID管理命令mdadm详解

mdadm是linux下用于创建和管理软件RAID的命令&#xff0c;是一个模式化命令。但由于现在服务器一般都带有RAID阵列卡&#xff0c;并且RAID阵列卡也很廉价&#xff0c;且由于软件RAID的自身缺陷(不能用作启动分区、使用CPU实现&#xff0c;降低CPU利用率)&#xff0c;因此在生产…

Spring、SpringBoot常见面试题与答案

Spring Spring Bean 的作用域有哪些&#xff1f;它的注册方式有几种&#xff1f; Spring 容器中管理一个或多个 Bean&#xff0c;这些 Bean 的定义表示为 BeanDefinition 对象&#xff0c;具体包含以下重要信息&#xff1a; Bean 的实际实现类&#xff1b;Bean 的引用或者依赖…