Java 8 Stream介绍及使用2
(原) stream中另一些比较常用的方法.
1、
public static<T> Stream<T> generate(Supplier<T> s)
通过generate返回一个Stream对象,接收一个 Supplier函数
例如:
Stream stream8 = Stream.generate(UUID.randomUUID()::toString);
2、
Optional<T> findFirst();
This is a short-circuiting terminal operation
这是一个终止操作,返回一个Optional,为什么是Optional而不是一个对象T呢?因为Stream中可能会有空的情况,就像这样Stream stream8 = Stream.empty();
如果是这样,那么findFirst()可能会返回null值,所以才用了Optional来规避空值的情况。
例如:
Stream stream8 = Stream.generate(UUID.randomUUID()::toString);
stream8.findFirst().ifPresent(System.out::println);
3、
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
Returns an infinite sequential ordered {@code Stream} produced by iterative
application of a function {@code f} to an initial element {@code seed}
producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
*{@code f(f(seed))}, etc.
用这个种子元素seed,通过迭代f,返回一个无限的串行的有序的流元素,
最后的stream的结果是一个seed ,f(seed),f(f(seed)) … 的结果。
由于这个方法是无限循环的,所以往往会跟limit终止操作配合使用。
它的第2个参数UnaryOperator是这样定义的:
public interface UnaryOperator<T> extends Function<T, T>
如果它的apply方法接收参数和返回参数是同一类型,是一个一元的Function函数
例如:
Stream.iterate(1,i -> i + 2).limit(3).forEach(System.out::println);
返回的结果将是1、3、5。
4、
Stream<T> limit(long maxSize); Returns a stream consisting of the elements of this stream, truncated
to be no longer than {@code maxSize} in length
返回一个长度不超过给定参数maxSize大小的stream
Stream<T> skip(long n); Returns a stream consisting of the remaining elements of this stream
after discarding the first {@code n} elements of the stream
返回一个丢弃了前n个元素之后的stream。
例如:用iterate生成一个从1开始往后加1的stream,先限定这个stream长度为5,再忽略前2个,取后3个元素输出。
Stream.iterate(1, i -> i + 1).limit(5).skip(2).forEach(System.out::println);
5、
Stream<T> distinct()
没啥说的,去重用的。
例如:
IntStream.of(1,1,3,4,5,6,4).distinct().forEach(System.out::println);
返回1,3,4,5,6
6 、
Optional<T> max(Comparator<? super T> comparator)
Optional<T> min(Comparator<? super T> comparator)
求最大最小值,一般而言,如果是数字可用IntStream,IntStream中的求最大值,最小值是不带参数的,max(),min(),另外还提供了一个sum()求和方法。

如果IntStream是一个空对象,那么sum可以返回0,而min,max是一个null , 所以这里sum的返回值用的是int,而min和max返回值是OptionalInt,用于规避值为null的情况,所以一般可以这么写.
IntStream.of(1,2,3,4,5).max().ifPresent(System.out::println);
针对于IntStream的统计方法,它还额外提供了一个方法:
IntSummaryStatistics summaryStatistics()
IntSummaryStatistics 这个类,它也提供了数值统计的常用方法,如count,sum,min,max ,average等
例如:
IntSummaryStatistics intSummaryStatistics = IntStream.of(1, 2, 3, 4, 5).summaryStatistics();
System.out.println(intSummaryStatistics.getMax());
System.out.println(intSummaryStatistics.getMin());
System.out.println(intSummaryStatistics.getAverage());
使用场景:
1、将stream元素去重
Stream<String> stream1 = Stream.of("happy new", "new year", "happy year","new happy");
stream1.map(item -> item.split(" ")).flatMap(Arrays::stream).distinct().collect(Collectors.toList()).forEach(System.out::println);
2、如何将二个集合中的元素做笛卡尔集,交叉拼接
List<String> list1 = Arrays.asList("hello","world","today");
List<String> list2 = Arrays.asList("a","b","c");
list1.stream().flatMap(item -> list2.stream().map(item2 -> item + " " + item2)).collect(Collectors.toList()).forEach(System.out::println);
3、如果有一个对象Student,包含二个属性,name和age,在一个student集合中如何分组。
class Student{
private String name;
private Integer age;
public Student(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;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Student s1 = new Student("zhangsan", 30);
Student s2 = new Student("lisi", 26);
Student s3 = new Student("wangwu",30);
Student s4 = new Student("lisi",22);
//根据姓名分组
List<Student> list3 = Arrays.asList(s1, s2, s3, s4);
Map<String,List<Student>> map3 = list3.stream().collect(Collectors.groupingBy(Student::getName));
map3.forEach((key,value) -> System.out.println(key+":"+value));
//查看根据姓名分组后每组多少数量
List<Student> list4 = Arrays.asList(s1, s2, s3, s4);
Map<String,Long> map4 = list4.stream().collect(Collectors.groupingBy(Student::getName,Collectors.counting()));
map4.forEach((key,value) -> System.out.println(key+":"+value));
//查看根据姓名分组后,每个组平均年龄
List<Student> list5 = Arrays.asList(s1, s2, s3, s4);
Map<String,Double> map5 = list5.stream().collect(Collectors.groupingBy(Student::getName,Collectors.averagingDouble(Student::getAge)));
map5.forEach((key,value) -> System.out.println(key+":"+value));
//查看根据年龄分区,25岁以上为一个区,分区类似于分组,但是只有二个组,一个true,一个false,
List<Student> list6 = Arrays.asList(s1, s2, s3, s4);
Map<Boolean,List<Student>> map6 = list6.stream().collect(Collectors.partitioningBy(s -> s.getAge() > 25));
map6.forEach((key,value) -> System.out.println(key+":"+value));
例子请看这里:https://github.com/LeeScofield/java8
Java 8 Stream介绍及使用2的更多相关文章
- Java 8 Stream介绍及使用1
(原) stream的内容比较多,先简单看一下它的说明: A sequence of elements supporting sequential and parallel aggregate * o ...
- Java 8 Stream API详解--转
原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...
- java之stream(jdk8)
一.stream介绍 参考: Java 8 中的 Streams API 详解 Package java.util.stream Java8初体验(二)Stream语法详解 二.例子 im ...
- Java笔记:Java 流(Stream)、文件(File)和IO
更新时间:2018-1-7 12:27:21 更多请查看在线文集:http://android.52fhy.com/java/index.html java.io 包几乎包含了所有操作输入.输出需要的 ...
- Java 8 Stream
1.关于Java8部分新特性介绍 Java8的新特性很多,在此就不一一介绍了,这里只说一下我自己在工作用用得比较多的几点: 1.1.Lambda表达式 Lambda允许把函数作为一个方法的参数(函数作 ...
- java.util.stream 库简介
Java Stream简介 Java SE 8 中主要的新语言特性是拉姆达表达式.可以将拉姆达表达式想作一种匿名方法:像方法一样,拉姆达表达式具有带类型的参数.主体和返回类型.但真正的亮点不是拉姆达表 ...
- Java - 17 Java 流(Stream)、文件(File)和IO
Java 流(Stream).文件(File)和IO Java.io包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io包中的流支持很多种格式,比如:基本类型. ...
- Java之Stream流
Stream流的初步学习 初次学习Stream流的学习笔记,学习之前先了解一下函数式接口 概述 API是一个程序向使用者提供的一些方法,通过这些方法就能实现某些功能.所以对于流API来 说,重点是怎么 ...
- Java总结:Java 流(Stream)、文件(File)和IO
更新时间:2018-1-7 12:27:21 更多请查看在线文集:http://android.52fhy.com/java/index.html java.io 包几乎包含了所有操作输入.输出需要的 ...
随机推荐
- 4. [mmc subsystem] mmc core(第四章)——host模块说明
零.说明 对应代码drivers/mmc/core/host.c,drivers/mmc/core/host.h. 为底层host controller driver实现mmc host的申请以及注册 ...
- CF592D Super M
嘟嘟嘟 首先这题虽然不是很难,但是黄题是不是有点过分了--好歹算个蓝题啊. 手玩样例得知,这哥们儿瞬移到的城市\(A\)一定是这些被攻击的城市构成的树的一个叶子,然后他经过的最后一个城市\(B\)和\ ...
- 判断JS数据类型的四种方法
在 ECMAScript 规范中,共定义了 7 种数据类型,分为 基本类型 和 引用类型 两大类,如下所示: 基本类型:String.Number.Boolean.Symbol.Undefined.N ...
- 浅析 jQuery 内部架构设计
jQuery 对于大家而言并不陌生,因此关于它是什么以及它的作用,在这里我就不多言了,而本篇文章的目的是想通过对源码简单的分析来讨论 jQuery 的内部架构设计,以及 jQuery 是如何利用Jav ...
- Android 开发者必知必会的权限管理知识
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/OQRHEufCUXBA3d3DMZXMKQ 导语 本 ...
- Docker 容器与宿主机网段冲突导致网络无法 ping 通的解决方案
docker 容器网络默认使用 bridge 桥接模式,正常情况下,容器会使用 daemon.json 中定义的虚拟网桥来与宿主机进行通讯. 最近更新 Docker for mac 之后,发现以前容器 ...
- 以Windows服务方式运行.NET Core程序
在之前一篇博客<以Windows服务方式运行ASP.NET Core程序>中我讲述了如何把ASP.NET Core程序作为Windows服务运行的方法,而今,我们又遇到了新的问题,那就是: ...
- 视频直播 object 标签属性详解
最近在做视频直播这一块的,html5的video不能实现此功能,在网上查找了资料,觉得很有用. 一.介绍: 我们要在网页中正常显示flash内容,那么页面中必须要有指定flash路径的标签.也就是OB ...
- 4年前端、2年CTO:一个非科班程序员的真实奋斗史
1.引言 我,Scott,一家创业公司的 CTO. 从业6年却很少写文章,近一年来接触了几十个刚毕业的前端新人,也面试了100多个前端工程师和Nodejs工程师,对于前端发展的这个职业算是有些感触 ...
- 为什么从前那些.NET开发者都不写单元测试呢?
楔子 四年前我虽然也写了很多年代码,由于公司虽然规模不小,却并非一家规范化的软件公司,因此在项目中严格意义上来说并没有架构设计.也不写单元测试,后来有幸加入了一家公司,这家公司虽然也是一家小公司,但是 ...