一、Stream是什么?

  是数据通道,用于操作数据源(集合、数组等)所生成的元素序列。集合讲的是数据,流讲的是计算。

  注意:

    Stream不会存储元素。

    Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。

    Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

  Stream操作的三个步骤:

    创建Stream:  一个数据源(如:集合、数组),获取一个流

    中间操作:一个中间操作链,对数据源的数据进行处理

    终止操作(终端操作):一个终止操作,执行中间操作链,并产生结果。

二、创建Stream

  1、Java8中的Collection接口被扩展,提供了两个获取流的方法。

    default Stream<E> stream() : 返回一个顺序流

    default Stream<E> parallelStream() : 返回一个并行流

//1. Collection 提供了两个方法  stream() 与 parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流

  2、由数组创建流

    Java8中的Arrays的静态方法stream()可以获取数组流。

    static <T> Stream<T> stream(T[] array): 返回一个流

    重载形式,能够处理基本类型的数组:

    public static IntStream stream(int[] array)

    public static LongStream stream(long[] array)

    public static DoubleStream stream(double[] array)

//2. 通过 Arrays 中的 stream() 获取一个数组流
Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);

  3、由值创建流

    可以使用静态方法Stream.of(),通过显示值创建一个流。它可以接收任意数量的参数。

    public static<T> Stream<T> of(T... values) : 返回一个流

Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);

  4、由函数创建无限流

    可以使用静态方法 Stream.iterate() 和Stream.generate(), 创建无限流。

    迭代:public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)

    生成:public static<T> Stream<T> generate(Supplier<T> s)  

//迭代
Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
stream3.forEach(System.out::println);
//生成
Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);

三、Stream的中间操作

  多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“”惰性求值“”。

  1、筛选与切片

    

  ①filter

    //内部迭代:迭代操作 Stream API 内部完成
@Test
public void test2(){
//所有的中间操作不会做任何的处理
Stream<Employee> stream = emps.stream()
.filter((e) -> {
System.out.println("测试中间操作");
return e.getAge() <= 35;
}); //只有当做终止操作时,所有的中间操作会一次性的全部执行,称为“惰性求值”
stream.forEach(System.out::println);
}
    //外部迭代
@Test
public void test3(){
Iterator<Employee> it = emps.iterator(); while(it.hasNext()){
System.out.println(it.next());
}
}

  ②limit

    @Test
public void test4(){
emps.stream()
.filter((e) -> {
System.out.println("短路!"); // && ||
return e.getSalary() >= 5000;
}).limit(3)
.forEach(System.out::println);
}

  ③skip

    @Test
public void test5(){
emps.parallelStream()
.filter((e) -> e.getSalary() >= 5000)
.skip(2)
.forEach(System.out::println);
}

  ④distinct

    @Test
public void test6(){
emps.stream()
.distinct()
.forEach(System.out::println);
}

  2、映射

    ①映射

  

@Test
public void test1(){
Stream<String> str = emps.stream()
.map((e) -> e.getName()); System.out.println("-------------------------------------------"); List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee"); Stream<String> stream = strList.stream()
.map(String::toUpperCase); stream.forEach(System.out::println); Stream<Stream<Character>> stream2 = strList.stream()
.map(TestStreamAPI1::filterCharacter); stream2.forEach((sm) -> {
sm.forEach(System.out::println);
}); System.out.println("---------------------------------------------"); Stream<Character> stream3 = strList.stream()
.flatMap(TestStreamAPI1::filterCharacter); stream3.forEach(System.out::println);
}
    public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>(); for (Character ch : str.toCharArray()) {
list.add(ch);
} return list.stream();
}

  ②排序

   

    @Test
public void test2(){
emps.stream()
.map(Employee::getName)
.sorted()
.forEach(System.out::println); System.out.println("------------------------------------"); emps.stream()
.sorted((x, y) -> {
if(x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return Integer.compare(x.getAge(), y.getAge());
}
}).forEach(System.out::println);
}

  ③Stream终止操作

  终止操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer、甚至是void。

  查找与匹配:

  

  

  match

    @Test
public void test1(){
boolean bl = emps.stream()
.allMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl); boolean bl1 = emps.stream()
.anyMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl1); boolean bl2 = emps.stream()
.noneMatch((e) -> e.getStatus().equals(Status.BUSY)); System.out.println(bl2);
}

  find

    @Test
public void test2(){
Optional<Employee> op = emps.stream()
.sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst(); System.out.println(op.get()); System.out.println("--------------------------------"); Optional<Employee> op2 = emps.parallelStream()
.filter((e) -> e.getStatus().equals(Status.FREE))
.findAny(); System.out.println(op2.get());
}

  count、max、min

    @Test
public void test3(){
long count = emps.stream()
.filter((e) -> e.getStatus().equals(Status.FREE))
.count(); System.out.println(count); Optional<Double> op = emps.stream()
.map(Employee::getSalary)
.max(Double::compare); System.out.println(op.get()); Optional<Employee> op2 = emps.stream()
.min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(op2.get());
}

进行了终止操作后不能再次使用

    //注意:流进行了终止操作后,不能再次使用
@Test
public void test4(){
Stream<Employee> stream = emps.stream()
.filter((e) -> e.getStatus().equals(Status.FREE)); long count = stream.count(); stream.map(Employee::getSalary)
.max(Double::compare);
}

  归约

  

  备注:map和reduce的连接通常称为map-reduce模式,因Google 用它来进行网络搜索而出名。

@Test
public void test1(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer sum = list.stream()
.reduce(0, (x, y) -> x + y); System.out.println(sum); System.out.println("----------------------------------------");
//薪资总和
Optional<Double> op = emps.stream()
.map(Employee::getSalary)
.reduce(Double::sum); System.out.println(op.get());
}
//需求:搜索名字中 “六” 出现的次数
@Test
public void test2(){
Optional<Integer> sum = emps.stream()
.map(Employee::getName)
.flatMap(TestStreamAPI1::filterCharacter)
.map((ch) -> {
if(ch.equals('六'))
return 1;
else
return 0;
}).reduce(Integer::sum); System.out.println(sum.get());
}

  收集

  

  

    //collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
@Test
public void test3(){
List<String> list = emps.stream()
.map(Employee::getName)
.collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("----------------------------------"); Set<String> set = emps.stream()
.map(Employee::getName)
.collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("----------------------------------"); HashSet<String> hs = emps.stream()
.map(Employee::getName)
.collect(Collectors.toCollection(HashSet::new)); hs.forEach(System.out::println);
}
//分组
@Test
public void test5(){
Map<Status, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(map);
}
//多级分组
@Test
public void test6(){
Map<Status, Map<String, List<Employee>>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
}))); System.out.println(map);
}
//分区
@Test
public void test7(){
Map<Boolean, List<Employee>> map = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000)); System.out.println(map);
}
  Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

  

  

  

二、StreamAPI的更多相关文章

  1. Java8新特性——StreamAPI(二)

    1. 收集器简介 收集器用来将经过筛选.映射的流进行最后的整理,可以使得最后的结果以不同的形式展现. collect方法即为收集器,它接收Collector接口的实现作为具体收集器的收集方法. Col ...

  2. 010-jdk1.8版本新特性二-Optional类,Stream流

    1.5.Optional类 1.定义 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个 ...

  3. Java8新特性——StreamAPI 的使用

    StreamAPI的说明 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API. Stream API ( java.util.stream) 把真正的 ...

  4. 【小程序分享篇 二 】web在线踢人小程序,维持用户只能在一个台电脑持登录状态

    最近离职了, 突然记起来还一个小功能没做, 想想也挺简单,留下代码和思路给同事做个参考. 换工作心里挺忐忑, 对未来也充满了憧憬与担忧.(虽然已是老人, 换了N次工作了,但每次心里都和忐忑). 写写代 ...

  5. 前端开发中SEO的十二条总结

    一. 合理使用title, description, keywords二. 合理使用h1 - h6, h1标签的权重很高, 注意使用频率三. 列表代码使用ul, 重要文字使用strong标签四. 图片 ...

  6. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

  8. 谈谈一些有趣的CSS题目(十二)-- 你该知道的字体 font-family

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  9. MIP改造常见问题二十问

    在MIP推出后,我们收到了很多站长的疑问和顾虑.我们将所有疑问和顾虑归纳为以下二十个问题,希望对大家理解 MIP 有帮助. 1.MIP 化后对其他搜索引擎抓取收录以及 SEO 的影响如何? 答:在原页 ...

随机推荐

  1. Cow Relays 【优先队列优化的BFS】USACO 2001 Open

    Cow Relays Time Limit: 1000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Tota ...

  2. 【CSS】易错

    1.外边距默认是透明的,因此不会遮挡其后的任何元素.2.背景应用于由内容和内边距.边框组成的区域.3.外边距可以是负值,而且在很多情况下都要使用负值的外边距.4.不要给元素添加具有指定宽度的内边距,而 ...

  3. Redis配置文件(1)units/includes/GENERAL/SECURITY/LIMITS

    redis.conf文件 在Linux进行文件的查看! units单位: # Note on units: when memory size is needed, it is possible to ...

  4. Selenium应用代码(登录)

    这篇可以不看,主要是为了以后的应用代码(传参)做铺垫. import java.awt.Rectangle; import java.awt.image.BufferedImage;import ja ...

  5. Spring知识概括梳理

    1. Spring 容器 http://blog.csdn.net/chenssy/article/details/8188570 2. Spring 注解 1)@Autowired http://b ...

  6. 两种方式(xml+代码)构建SqlSessionFactory+完整实现

    首先创建类.接口.数据库: entity包下Admin类: package com.wbg.springJavaConfig.entity; public class Admin { private ...

  7. React Native IOS ---基础环境搭建(前端架构师)

    React Native -IOS 开发环境搭建 web架构(基础) 安装依赖 * 必须安装的依赖有:Node.Watchman 和 React Native 命令行工具以及 Xcode. npm 镜 ...

  8. HTML5——前端预处理技术(Less、Sass、CoffeeScript)

    一.Less 1.1.概要 Less是一种动态样式语言,Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性,使 CSS 更易维护和扩展. Less 将 C ...

  9. VM中Centos安装

    本例中的vm是12版本的. VM设置 首先是vm的设置,相当于是买电脑的过程 首先文件 -> 新建虚拟机 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 然后 点击完成之 ...

  10. grid 布局的使用

    grid 布局的使用 css 网格布局,是一种二维布局系统. 浏览器支持情况:老旧浏览器不支持, 概念: 网格容器.元素应用dispalay:grid,它是所有网格项的父元素. <div cla ...