Java0steam_Java学习 - Stream 使用

Java Stream使用

这段时间在学数据库和Java,发现Java的Stream实际上和数据库的查询操作非常类似。这里简单介绍Stream的用法,并和Sql Server中的操作联系起来。

此文为初学Stream所写,以后对Stream有更深的理解后会重写

当我们使用一个流的时候,通常包括三个基本步骤:

获取一个数据源(source)

数据转换

执行操作获取想要的结果

每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道,如下图所示。

ba832f29af9355c4fe65ee610a31501e.png

一、创建 stream

有多种方式生成 Stream Source:

从 Collection 和数组

Collection.stream()

Collection.parallelStream()

Arrays.stream(T array) or Stream.of()

从 BufferedReader

java.io.BufferedReader.lines()

静态工厂

java.util.stream.IntStream.range()

java.nio.file.Files.walk()

自己构建

java.util.Spliterator

其它

Random.ints()

BitSet.stream()

Pattern.splitAsStream(java.lang.CharSequence)

JarFile.stream()

创建Stream示例

// 1. Individual values

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

// 2. Arrays

String [] strArray = new String[] {"a", "b", "c"};

stream = Stream.of(strArray);

stream = Arrays.stream(strArray);

// 3. Collections

List list = Arrays.asList(strArray);

stream = list.stream();

二、stream 操作

stream的操作分为两大类,一类为中间操作,一类为终端操作。

中间操作:返回值仍然为一个流,不会消耗流

终端操作:返回最终结果;终端操作会消耗掉流,使之不再可用

1.stream.filter()

stream.filter() 是一个中间操作

baf7e4cce39d5f9d6022f5e31442b653.png

stream.filter()用于对stream进行某种筛选,stream.filter() 相当于Sql server 中,from ... where ...

在filter()中应当给出筛选条件,准确的说,应该实现Predicate接口,这个接口将被应用于stream中的每一个元素,判断其是否应该被包含在结果stream中。

这个接口只有一个抽象方法待用户实现

4f0a8ac23103257d244c91df437ce687.png

抽象方法应该返回一个布尔值,当布尔值为真时,stream.filter()将这个元素包含在结果stream中

stream.filter()使用示例:创建Integer流,然后筛选出偶数

ArrayList arrlist = new ArrayList();

Stream st = arrlist.stream();

Stream st2 = st.filter(new Predicate() {

@Override

public boolean test(Integer arg0) {

return arg0 % 2 == 0;

}

});

还可以用lambda表达式来实现

ArrayList arrlist = new ArrayList();

Stream st = arrlist.stream();

Stream st2 = st.filter((o1)->(o1 % 2 == 0));

关于Predicate接口,它还有.and(),.or(),.negate(),.isEqual()四个默认方法,这里不多介绍。但这些方法也十分常用,对于稍微复杂一点的逻辑就需要使用。

使用Precicate接口需要导入

import java.util.function.Predicate;

9f53b92f3ac6a26864a514ec474d499a.png

2.stream.map()

stream.map()是一个中间操作

7429ab47e7a0fbf260ab148a64bb7dcd.png

stream.map()用于对stream进行某种映射,stream.map() 相当于Sql server 中,select

虽然这么说不太恰当,因为Sql sever 的select实际上时 SQL语言中 \(\sigma , \prod\)的加和,而stream.map() 应该是\(\prod\).

在stream.map()中应该指定转换条件,准确的说,应该实现一个Function()接口,这个接口将被用于stream的每一个元素,将元素按照一定的映射关系映射成新的元素。

Function接口的参数意义

2466ec6f40dd2b7c394f1603bcef48a8.png

使用Function接口需要导入

import java.util.function.Function;

这个接口只有一个抽象方法待用户实现

e31839b5728a09aa179b931fbb065331.png

抽象方法apply() 接受一个T类型的参数,返回一个R类型的结果

stream.map()使用示例:创建Integer流,然后映射到其原值的两倍

ArrayList arrlist = new ArrayList();

for(int i = 1; i <= 5; i++) {

arrlist.add(i);

}

Stream st = arrlist.stream();

Stream st2 = st.map(new Function() {

@Override

public Integer apply(Integer arg0) {

return arg0 * 2;

}

});

ArrayList ans = new ArrayList();

ans = (ArrayList) st2.collect(Collectors.toList());

for(Integer i : ans) {

System.out.print(i + " ");

}

还可以用lambda表达式来实现

// 初学可以先不这么写

ArrayList ans = (ArrayList)arrlist.stream()

.map((o1)->(2*o1))

.collect(Collectors.toList());

stream.map() 的几种其他形式

IntStream mapToInt(ToIntFunction super T> mapper);

LongStream mapToLong(ToLongFunction super T> mapper);

DoubleStream mapToDouble(ToDoubleFunction super T> mapper);

这三者实际上是对\(Function\) 中 R的固定封装

3.stream.flatMap()

stream.flatMap()是一个中间操作

4d35cda63c5f0ee2fb3ddb444671fd12.png

stream.flatMap()和stream.map()都是进行映射的方法,区别在于,flatMap()处理的元素类型仍是流,flagMap用于将若干个流先拆分成若干个单个元素,再整合成一个流,即流的合并。

简单来说,flatMap()将集合的集合降维成单个元素的集合

实例: 将数组\([[1,2,3],[4,5,6],[7,8],[9]]\)转化为[1,2,3,4,5,6,7,8,9]

ArrayList> list_2 = new ArrayList<>();

list_2.add(new ArrayList<>(Arrays.asList(1,2,3)));

list_2.add(new ArrayList<>(Arrays.asList(4,5,6)));

list_2.add(new ArrayList<>(Arrays.asList(7,8)));

list_2.add(new ArrayList<>(Arrays.asList(9)));

ArrayList list_1 = (ArrayList) list_2.stream()

// list_2.stream() 为 "[1,2,3]" "[4,5,6]" "[7,8]" "[9]" 每个""表示流的不同元素

.flatMap((o1)->(o1).stream())

// 以 o1 = "[1,2,3]"为例,(o1)->(o1).stream() 转化为"1","2","3"

.collect(Collectors.toList());

for(Integer i : list_1) {

System.out.print(i+" ");

}

stream.flagMap()的几种其他形式

IntStream flatMapToInt(Function super T, ? extends IntStream> mapper);

LongStream flatMapToLong(Function super T, ? extends LongStream> mapper);

DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> mapper);

这三者实际上是对\(Function\) 中 R的固定封装

4.stream.allMatch() ,stream.anyMatch() 和 stream.noneMatch()

stream.allMatch() 和 stream.anyMatch()均为终端操作

da97a0775382658d926b94f8b8827803.png

传入一个Predicate函数式接口,用于指定条件

5.stream.collect()

stream.collect()为终端操作

7818c790464944b2824d01474021083c.png

Stream的核心在于collect,即对数据的收集。

用法一:将流转化为Collection或Map

Collectors.toCollection() 将数据转换成Collection,只要是Collection的实现都可以,例如ArrayList,HashSet,该方法能够接受一个Collection对象

示例:

//List

Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toCollection(ArrayList::new));

//Set

Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toCollection(HashSet::new));

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toList());

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toSet());

// Stream.of(1,2,3,4,5,6,7,8,9).collect(Collectors.toMap(key,value));

用法二:字符串聚合规约

Collectors.joining(),拼接,有三个重载方法,底层实现是StringBuilder,通过append方法拼接到一起,并且可以自定义分隔符(这个感觉还是很有用的,很多时候需要把一个list转成一个String,指定分隔符就可以实现了,非常方便)、前缀、后缀。

Student studentA = new Student("20190001", "小明");

Student studentB = new Student("20190002", "小红");

Student studentC = new Student("20190003", "小丁");

//使用分隔符:201900012019000220190003

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining());

//使用^_^ 作为分隔符

//20190001^_^20190002^_^20190003

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining("^_^"));

//使用^_^ 作为分隔符

//[]作为前后缀

//[20190001^_^20190002^_^20190003]

Stream.of(studentA, studentB, studentC)

.map(Student::getId)

.collect(Collectors.joining("^_^", "[", "]"));

用法三:统计个数

Collectors.counting() 统计元素个数,这个和Stream.count() 作用都是一样的,返回的类型一个是包装Long,另一个是基本long,但是他们的使用场景还是有区别的,这个后面再提。

// Long 8

Stream.of(1,0,-10,9,8,100,200,-80)

.collect(Collectors.counting());

//如果仅仅只是为了统计,那就没必要使用Collectors了,那样更消耗资源

// long 8

Stream.of(1,0,-10,9,8,100,200,-80)

.count();

用法四:集合分组

Collectos.groupingBy()实现集合分组,返回值为一个Map

假如现在有一个实体Student

public class Student {

private String name;

private int score;

private int age;

public Student(String name,int score,int age){

this.name = name;

this.score = score;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getScore() {

return score;

}

public void setScore(int score) {

this.score = score;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

现在对其按照Name分组

Map> StrListStrMap = students.stream()

.collect(Collectors.groupingBy(Student::getName));

6.stream.forEach() 和

stream.forEach() 终端操作

stream.forEach()遍历流中的每一个元素,不一定依靠流的顺序,而stream.forEachOrdered()按照流的顺序遍历。

Stream.of(1,2,3,4,5,6).forEach(System.out::println);

7.stream.max() , stream.min() , stream.count()

三个终端操作

stream.max()返回流中的最大值

stream.min()返回流中的最小值

未传入Comparator则填null,默认用Comparable的compareTo函数比较。

stream.count()返回流中元素个数

8.stream.findAny()

返回流中任意一个元素,如果流为空,返回一个空的Optional.

List list = Arrays.asList(1, 2, 3, 4, 5, 6);

Optional any = list.stream().findAny();

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

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

相关文章

mysql初始化很慢_mysql初始化报错

/var/log/mysql.log 日志报错如上图所示解决方法&#xff1a;SELinux惹的祸通俗的讲就是linux服务器的安全策略解决&#xff1a;临时关闭&#xff1a;setenforce 0永久关闭需要修改配置文件&#xff0c;重启机器&#xff1a;修改/etc/selinux/config 文件将SELINUXenforcing改为…

百度java的线程技术_自我提升(基础技术篇)——java线程简介

前言&#xff1a;虽然自己平时都在用多线程&#xff0c;也能完成基本的工作需求&#xff0c;但总觉得&#xff0c;还是对线程没有一个系统的概念&#xff0c;所以&#xff0c;查阅了一些资料&#xff0c;理解那些大神和官方的资料&#xff0c;写这么一篇关于线程的文章本来想废…

java调用扫描仪识别文字_Java使用扫描仪读取文件输入

示例Scanner scanner null;try {scanner new Scanner(new File("Names.txt"));while (scanner.hasNext()) {System.out.println(scanner.nextLine());}} catch (Exception e) {System.err.println("发生异常&#xff01;");} finally {if (scanner ! nul…

d3 tip mysql_mysql

字符&#xff1a;char(10)->定长、10个字符宽度。如果右侧不够&#xff0c;则空格补齐&#xff0c;取出来的时候删除空格。varchar(10)->变长、最多10个字符如&#xff1a;存姓名的时候&#xff0c;没必要为了那几个长度去使用varchar&#xff0c;使用定长去存储会提高效…

java string rt_如何使jvm加载我的java.lang.String而不是rt.jar中的那个

我认真研究了Java类加载器。现在&#xff0c;我想编写一个与rt.jar中的类之一具有相同的包名称和类名称的类。例如&#xff0c;我自己编写一个java.lang.String类&#xff0c;以及如何打破父级委托模型以使jvm加载我的java.lang.String而不是rt.jar中的类。重新编辑Thx&#xf…

php在线语音,PHP在线语音合成

这篇文章主要介绍了PHP在线语音合成&#xff0c;有着一定的参考价值&#xff0c;现在分享给大家&#xff0c;有需要的朋友可以参考一下在线语音合成 PHP SDKhttp://yuyin.baidu.com/docs/tts/194PHP SDK文档简介Hi&#xff0c;您好&#xff0c;欢迎使用百度语音合成服务。本文档…

php工厂模式和单例模式,php 设计模式之工厂模式、单例模式、注册树模式

php 设计模式之工厂模式、单例模式、注册树模式在软件工程中&#xff0c;创建型设计模式承担着对象创建的职责&#xff0c;尝试创建适合程序上下文的对象&#xff0c;对象创建设计模式的产生是由于软件工程设计的问题&#xff0c;具体说是向设计中增加复杂度&#xff0c;创建型…

php 正则匹配unicode,PHP中正则表达式对UNICODE字符码的匹配方法

网友ainiaa的问题是PHP代码如下代码如下:$words "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!#$%^&*()_-[]\\,./{}|<>?\"你好啊我们";$otherStrpreg_replace("/[chr(128)-chr(256)]/is"," ",$words);ech…

iis7怎么安装php7,Linux下如何安装php7

Linux下安装php7的方法&#xff1a;首先安装依赖包&#xff0c;并下载解压安装包&#xff1b;然后检查环境的依赖关系&#xff0c;并编译安装&#xff1b;接着将【php.ini-production】改名为【php.ini】&#xff1b;最后复制启动脚本&#xff0c;并启动PHP即可。Linux下安装ph…

php长轮询阻塞,ajax长轮询时php被阻塞

刚接触实时通讯这块&#xff0c;知道用websocket更高效&#xff0c;但我想了解轮询的实现过程&#xff0c;循序渐进短轮询用定时器setInterval已经实现了&#xff0c;但长轮询时后台进入死循环模块导致整个网站的php网页无响应&#xff0c;比如刷新页面、提交消息都没法进行。具…

php隐藏路径ngnix,thinkphp框架在nginx环境下去掉index.php路径显示

协助用户将apache下的一个网站迁移到nginx环境中&#xff0c;结果发现用户用的ThinkPHP框架做的开发&#xff0c;默认用的pathinfo。这是一个很头疼的问题&#xff0c;因为nginx不支持pathinfo&#xff0c;贸然一并打开也担心不安全。于是查询资料后整理如下&#xff1a;找到ap…

php curl 数据采集 空,PHP curl从网站返回空数组的数据

我想写一个PHP脚本来从www.snowbird.com/mountain-report/拉雪和其他数据通过LED阵列显示。我在获取需要的数据方面遇到麻烦。我似乎无法找到使其工作的方法。我能做这项工作吗&#xff1f;还是我需要去使用另一种语言&#xff1f;PHP curl从网站返回空数组的数据以下代码仅返回…

flux react php,Vue的Flux框架之Vuex状态管理器

学习vue之前&#xff0c;最重要是弄懂两个概念&#xff0c;一是“what”&#xff0c;要理解vuex是什么&#xff1b;二是“why”,要清楚为什么要用vuex。Vuex是什么&#xff1f;Vuex 类似 React 里面的 Redux 的状态管理器&#xff0c;用来管理Vue的所有组件状态。为什么使用Vue…

php config(),php config

PHP 的安装由于php是一个zip文件(非install版)&#xff0c;安装较为基本解压就行。把解压的 php5.2.1-Win32重命名为 php5。并复制到安装盘目录下。例如安装路径为 c:\php51 找到php目录下的 php.ini-dist或 php.ini.recommended文件&#xff0c;重命名为 php.ini,并复制到系统…

functions.php 在哪,functions.php常用函数

在设计WordPress主题时&#xff0c;在functions.php文件里添加一套通用的自定义函数将会大大提高开发效率&#xff0c;这样就不必每次开发主题时都需先查找然后复制同样的函数。这里记录一些常用的函数&#xff0c;方便以后使用&#xff01;给头部添加feed链接WordPress2.8以后…

java基本数据类型存储,JAVA - 基本数据类型的存储空间长度

1.整型类型 存储需求 bit数 取值范围 备注byte 1字节 1*8 &#xff0d;128&#xff5e;127short 2字节 2*8 &#xff0d;32768&#xff5e;32767int 4字节 4*8 (-2的31次方到2的31次方-1)long 8字节 8*8 (-2的63次方到2的63次方-1) 长整型数值后缀为LJAVA 没有无符号类型JAVA中…

matlab回调函数,matlabGUI回调函数介绍.pptx

matlabGUI回调函数介绍GUI开发环境的常用工具与回调函数和GUI程序文件GUI开发常用工具1、控件面板2、对象对齐工具3、对象浏览器4、tab顺序编辑器5、属性编辑器6、菜单编辑器7、M文件编辑器回调函数回调函数是控件接收到用户的操作时调用的特定函数&#xff0c;每个回调函数都是…

余额交易查询 php,深圳通余额查询的API

深圳通余额查询的API&#xff0c;可以通过深圳通号码查询到余额及卡有效期等信息。 用到Domxpath和Curl两方面的知识。 源码已托管到github&#xff0c;另外要加载个类&#xff1a;myclass 项目地址&#xff1a;https://github.com/skiy/dev 演示&#xff1a;http://api.oupag.…

食饵捕食者模matlab,几类食饵-捕食者模型的定性分析和数值模拟

摘要&#xff1a;生态问题一直是人们普遍关注的问题,特别是生态问题中的食饵-捕食者模型,则处于举足轻重的位置。如何更有效的控制、调节生物种群,使之保持良性发展,则具有非常重要的生态意义和应用价值。解决这类问题的主要工具是种群动力学模型,解决的依据是数学的理论和方法…

数组填充php,php数组入门教程之数组填充

本文介绍下&#xff0c;有关php数组之数组填充的一个例子&#xff0c;有需要的朋友参考下。在php编程中&#xff0c;对数组元素进行填充&#xff0c;可以使用array_fill()函数。来看下面的例子&#xff0c;array_fill()函数——填充数组函数&#xff1a;";print_r ($array…