jdk8新特性-stream
一、什么是流stream
1.可理解为高级版本的 Iterator
不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的。
2.单向,不可往复
数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
3.可并行化操作
迭代器:只能命令式地、串行化操作。当使用串行方式去遍历时,每个 item 读完后再读下一个 item。和迭代器不同,stream使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。
4.数据源本身可以是无限的
二、流的构成
1.构成的三个步骤
a.获取一个数据源(source)
b.数据转换
c.执行操作获取想要的结果。<每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道>。如下图所示:
eg:Student<id, name> List<Student> students = Lists.newArrayList(new Student(1, "学生1"), new Student(2, "学生2"), new Student(3, "学生3")); --- Source Stream<Student> studentStream = students.stream(); --- Stream Stream<Long> idStream = studentStream.map(student -> student.getId); --- Transforming List<Long> ids = idStream.collect(Collectors.toList()); --- Operations
三、流的常见3种方法
- Collection.stream()
- Collection.parallelStream()
- Arrays.stream(T array) or Stream.of()
- Stream.generate(Supplier<T> s)。<创建无限流,不常用>
// 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<String> list = Arrays.asList(strArray);
stream = list.stream();
四、基本类型的流的构造
三种对应的包装类型 Stream。
IntStream、LongStream、DoubleStream
或者
Stream<Integer>、Stream<Long>、Stream<Double>
eg:
IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);
IntStream.range(1, 3).forEach(System.out::println);
IntStream.rangeClosed(1, 3).forEach(System.out::println);
五、流转换为其它数据结构
// 1. Array
String[] strArray1 = stream.toArray(String[]::new);
// 2. Collection
List<String> list1 = stream.collect(Collectors.toList());
List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
Set set1 = stream.collect(Collectors.toSet());
Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
// 3. String
String str = stream.collect(Collectors.joining()).toString();
六、流的操作
- Intermediate:
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
- Terminal:
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
- Short-circuiting:
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
七、典型用法
1.map:
map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。作用:对流中的每一个元素进行操作。
1. 转换大写
List<String> output = wordList.stream().
map(String::toUpperCase).
collect(Collectors.toList());
说明:这段代码把每个单词转换为大写。
2. 平方数
List<Integer> nums = Arrays.asList(1, 2, 3, 4);
List<Integer> squareNums = nums.stream().
map(n -> n * n).
collect(Collectors.toList());
2.filter:
注意:这里要注意的是“过滤出”,而不是“过滤”,这是两个不同的意思!
1.留下偶数
Integer[] sixNums = {1, 2, 3, 4, 5, 6};
Integer[] evens = Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
注意:stream也是可以foreach的,没必要一定要转化成集合再foreach
3.forEach
作用:对stream中的每一个元素做聚合操作。
List<Integer> numbers = Lists.newArrayList(1, 2, 3, 4);
System.out.println(numbers.stream().mapToInt(Integer::intValue).sum()); --输出10
4.reduce
作用:对stream中的每一个元素做聚合操作。
Stream<Integer> reduceStream = Stream.of(1,2,3,4,5);
Optional<Integer> sumOption = reduceStream.reduce((x,y)->x+y);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算(注意:如果stream为null的话,就会产生无效的结果,需要使用Optional接收)
//Optional<Integer> sumOption = reduceStream.reduce(Integer::sum);//计算1+2+3+4+5,即对元素中的元素进行聚合计算,而map是对元素中的每一个元素分别计算
Integer result = reduceStream.reduce(0, Integer::sum);//0为标识值,即计算:0+1+2+。。+5,如果整个stream为null,就返回标识值。
System.out.println(result);
注意:以上是reduce的简单形式,即内联函数是(T,T)->T,即返回值和参数类型是一样的,返回值和参数类型不同的场景需要自己编写函数(用的较少)
5、Optional两种用法:
ifPresent(xxx):存在的就执行xxx,不存在就什么都不执行
orElse(xxx):存在就返回存在的值,不存在就返回xxx(可以理解为是默认值)
Stream<String> optionalStream = Stream.of("java","python","basic");
Optional<String> optionValue = optionalStream.filter(str->str.startsWith("p")).findFirst();
optionValue.ifPresent(str->System.out.println(str));//if optionalValue为true,即str存在,则输出str,当然也可以使用如下
String str = optionValue.orElse("xxx");//如果optionValue为false,即不存在以p开头的字符串时,使用"xxx"来替代
System.out.println(str);
5、limit skip contact1、limit(long size)作用:截取stream的前size个元素。
Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.limit(2).forEach(System.out::println);//截取前两个
2、skip(long size)作用:跳过stream的钱size个元素
Stream<String> streamSelf = Stream.of("python","basic","php");
streamSelf.skip(2).forEach(System.out::println);//跳过前两个
3、contact(Stream<T>,Stream<T>)作用:拼接两个stream
Stream<String> streamSelf = Stream.of("python","basic","php");
Stream<String> streamSelf2 = Stream.of("python2","basic2","php2");
Stream.concat(streamSelf, streamSelf2).forEach(System.out::println);
6.聚合函数
count max min findFirst findAny anyMatch allMatch noneMatch
Stream<String> streamSelf = Stream.of("python","basic","php","b");
System.out.println(streamSelf.count());//计算流中的元素个数
Optional<String> largest = streamSelf.max(String::compareToIgnoreCase);//寻找最大值
if(largest.isPresent()){
System.out.println(largest.get());
}
说明:min函数也一样。注意:Optional的使用,上边的是最差的一种形式,见"六"。
Optional<String> firstMatch = streamSelf.filter(str->str.startsWith("b")).findFirst();//寻找第一个符合条件的元素
firstMatch.ifPresent(System.out::println);//这是Optional的第一种用法
Optional<String> anyMatch = streamSelf.parallel().filter(str->str.startsWith("b")).findAny();//返回集合中符合条件的任意一个元素,对于并行处理非常好(因为多个线程只要有一个线程找到了,整个计算就会结束)
if(anyMatch.isPresent()){
System.out.println(anyMatch.get());//这里的结果可能是b,有可能是basic
}
boolean isAnyMatch = streamSelf.parallel().anyMatch(str->str.startsWith("c"));//集合中是否有一个满足条件
System.out.println(isAnyMatch);
Stream<String> streamSelf3 = Stream.of("basic","b");
boolean isAllMatch = streamSelf3.parallel().allMatch(str->str.startsWith("b"));//集合中是否所有元素都满足条件
System.out.println(isAllMatch);
boolean isAllNotMatch = streamSelf.parallel().noneMatch(str->str.startsWith("p"));//集合中是否没有一个元素满足条件
System.out.println(isAllNotMatch);
注意:
optional的最佳用法:ifPresent()-->如果有就输出,如果没有,什么都不做
parallel():将stream转为并行流,并行流的使用一定要注意线程安全
七、java8 :: 用法 (JDK8 双冒号用法)
就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下。
尽量用::去代替->,培养良好的代码习惯。
双冒号运算就是Java中的[方法引用],[方法引用]的格式是:
类名::方法名
注意,没有()号。
案例:
使用前:
person -> person.getAge();
使用双冒号后:
Person::getAge 使用前:
new HashMap<>()
使用双冒号后:
HsahMap :: new 使用前:
MyTest.printValur(x));
使用双冒号后:
MyTest :: printValur
参考链接
Streams API详解
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
Stream API
https://www.cnblogs.com/sunny3096/p/7159521.html
jdk8新特性-stream的更多相关文章
- JDK8新特性---stream流
项目上用到了stream流,找篇blog,转载一下,介绍下Stream流的用法. 1 流概述 流是 JDK8 新增的成员,允许以声明性方式处理数据集合,可以把 Stream 流看作是遍历数据集合的一 ...
- jdk8 新特性stream().map()
1.大写字符串列表 1.1 简单的Java示例将Strings列表转换为大写 TestJava8.java package com.mkyong.java8; import java.util.Arr ...
- jdk8新特性Stream
Stream的方法描述与实例 1,filter 过滤 Person p1 = new Person(); p1.setName("P1"); p1.setAge(10); Per ...
- 【记录】【java】JDK8新特性Stream方式遍历集合
由于是以流方式,所以怎么操作也不改变原来的集合 1.普通遍历forEach List<String> list = new ArrayList(); list.add("a&qu ...
- JDK8新特性:使用stream、Comparator和Method Reference实现集合的优雅排序
大家对java接口Comparator和Comparable都不陌生,JDK8里面Comparable还和以前一样,没有什么改动:但是Comparator在之前基础上增加了很多static和defau ...
- JDK8新特性关于Stream流
在Java1.8之前还没有stream流式算法的时候,我们要是在一个放有多个User对象的list集合中,将每个User对象的主键ID取出,组合成一个新的集合,首先想到的肯定是遍历,如下: 1 2 3 ...
- JDK8新特性一览
转载自:http://blog.csdn.net/qiubabin/article/details/70256683 官方新特性说明地址 Jdk8新特性.png 下面对几个常用的特性做下重点说明. 一 ...
- 一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)
面试涉及问题含有: Java JDK8新特性 集合(哈希冲突.HashMap的原理.自动排序的集合TreeSet) 多线程安全问题 String和StringBuffer JVM 原理.运行流程.内部 ...
- JDK8 新特性
JDK8 新特性目录导航: Lambda 表达式 函数式接口 方法引用.构造器引用和数组引用 接口支持默认方法和静态方法 Stream API 增强类型推断 新的日期时间 API Optional 类 ...
随机推荐
- 《深入理解JVM》第二章读书笔记
Java内存区域与内存溢出异常 运行时数据区域 JVM执行java程序的时候有一个运行时数据区,每个区域有自己的作用,了解这些区域有助于我们理解JVM.JVM运行时数据区如图所示: 程序计数器 该区域 ...
- JMeter测试WEB性能入门
一.JMeter介绍 1.Apache JMeter是什么 Apache JMeter 是Apache组织的开放源代码项目,是一个100%纯Java桌面应用,用于压力测试和性能测量.它最初被设计用于W ...
- 解决WPF图片模糊最佳方法
对于图片显示模糊相信很多人都遇到过,其实,有些图片会因为垂直分辨率/水平分辨率不同而造成在WPF界面上显示出现模糊. WPF默认是96Dpi,但有些图片可能是72DPI甚至更低或更高,这样就会出现图片 ...
- laravel with嵌套的渴求式加载
今天在通过需求表A查询场地类型表B,然后通过表B的场地类型id去查询表C场地类型名的时候遇到了一个小的问题. 需求表A的字段:id.user_id .name等等: 中间表B的字段:id.appeal ...
- SQL server reporting service - rsReportServerNotActivated error solution
描述: 今天在原有的数据库版本上增加了Reporting Service 功能,数据库完成安装后,没有发现ReportServer和 ReportServerTemp 两个数据库 于是从其他服务器上, ...
- December 17th 2016 Week 51st Saturday
Great minds have purpose, others only have wishes. 杰出的人有着目标,其他人只拥有愿望. Are you clear about the differ ...
- Wannafly挑战赛18 E 极差(线段树、单调栈)
Wannafly挑战赛18 E 极差 题意 给出三个长度为n的正整数序列,一个区间[L,R]的价值定义为:三个序列中,这个区间的极差(最大值与最小值之差)的乘积. 求所有区间的价值之和.答案对\(2^ ...
- 【[HNOI2012]矿场搭建】
抄题解真开心 我真是越来越菜了 这是点双的板子题,于是求出所有点双,之后讨论 如果点双里之有一个割点,那么如果这个割点炸了,这个点双就出不去了,于是我们得在这个点双内部除了这个割点位置放一个 如果有两 ...
- javascrict中innerhtml和innerText的关系
1.time.innerHTML 就是id为time的标签中所有包含的代码内容 比如 <div id='time'><a href='#'>time</a>< ...
- On Java 8中文版 英雄召集令
这是该项目的GITHUB地址:https://github.com/LingCoder/OnJava8 广招天下英雄,为开源奉献!让我们一起来完成这本书的翻译吧! 如果您在阅读本书的过程中有发现不明白 ...