文章目录

  • 一、Stream( 流 )是什么?
  • 二、Stream 的操作三个步骤
  • 三、创建Stream
  • 四、Stream 的中间操作
    • 4.1、筛选与切片
    • 4.2、 映射:(重点)
    • 4.3、 排序:
  • 五、Stream 的终止操作
    • 5.1、查找与匹配
    • 5.2、 归约:(重点)
    • 5.3、收集:(重点)
    • 5.4、分组
    • 5.5、分区
    • 5.6、前缀,后缀

一、Stream( 流 )是什么?

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

集合中的 **流 **讲的是数据,此处的 Stream(流) 讲的是计算!

注意:

  • Stream 自己不会存储元素。

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

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

二、Stream 的操作三个步骤

  • 创建Stream
    一个数据源(如:集合、数组),获取一个流
  • 中间操作
    一个中间操作链,对数据源的数据进行处理
  • 终止操作(终端操作)
    一个终止操作,执行中间操作链,并产生结果

三、创建Stream

1、Collection 提供了两个方法 stream() 与 parallelStream()

List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流

2、通过 Arrays 中的 stream() 获取一个数组流

Integer[] nums = new Integer[10];
Stream<Integer> stream2 = Arrays.stream(nums);

3、 通过 Stream 类中静态方法 of()

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

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

4、 创建无限流

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

//迭代
Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2);
stream4.limit(10).forEach(System.out::println);

//生成

Stream<Double> stream5 = Stream.generate(Math::random).limit(2);
stream5.forEach(System.out::println);

四、Stream 的中间操作

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

4.1、筛选与切片

  • filter : 接收 Lambda , 从流中排除某些元素。
  • limit : 截断流,使其元素不超过给定数量。
  • skip(n) : 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
  • distinct : 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素

示例:

public class TestStreamaAPI {    List<Employee> emps = Arrays.asList(new Employee(102, "李四", 59, 6666.66),new Employee(101, "张三", 18, 9999.99),new Employee(103, "王五", 28, 3333.33),new Employee(104, "赵六", 8, 7777.77),new Employee(104, "赵六", 8, 7777.77),new Employee(104, "赵六", 8, 7777.77),new Employee(105, "田七", 38, 5555.55));/*筛选与切片filter:接收 Lambda , 从流中排除某些元素。limit:截断流,使其元素不超过给定数量。skip(n) : 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补distinct : 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素*///内部迭代:迭代操作 Stream API 内部完成@Testpublic void test2(){//中间操作: 不会做任何的处理Stream<Employee> stream = emps.stream().filter((e) -> {System.out.println("测试中间操作");return e.getAge() <= 35;});//终止操作:一次性执行全部内容,称为“惰性求值”stream.forEach(System.out::println);}//外部迭代:自已写迭代@Testpublic void test3(){Iterator<Employee> it = emps.iterator();while(it.hasNext()){System.out.println(it.next());}}//只打印了两次“短路”,而不是4次。@Testpublic void test4(){emps.stream().filter((e) -> {System.out.println("短路!"); // &&  ||return e.getSalary() >= 5000;}).limit(2).forEach(System.out::println);}//只打印了两次“短路”,而不是4次。与test4()的区别是,取的是跳过了前面两条数据,取后面的两条数据 。@Testpublic void test5(){emps.parallelStream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);}//必须重写Employee的 hashCode() 和 equals(),否则去重功能不生效。@Testpublic void test6(){emps.stream().distinct().forEach(System.out::println);}
}

4.2、 映射:(重点)

map :接收 Lambda , 将元素转换成其他形式或提取信息。 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap : 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

@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");strList.stream().map(String::toUpperCase)     .forEach(System.out::println);System.out.println("=====================================");//将Employee 中的姓名提取出来emps.stream().map(Employee::getName).forEach(System.out::println);System.out.println("=====================================");//filterCharacter()方法是每个字符返回一个流,Stream<Stream<Character>> stream2 = strList.stream().map(TestStreamAPI1::filterCharacter);//  {{a,a,a},{b,b,b},{c,c,c}}stream2.forEach((sm) -> {sm.forEach(System.out::println); //{a,a,a,b,b,b,c,c,c}});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();
}

4.3、 排序:

  • sorted() :自然排序 ( Comparable )
  • sorted(Comparator com) : 定制排序
@Test
public void test2(){//自然排序,按照String 内置的Comparable 排序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 的终止操作

5.1、查找与匹配

allMatch :检查是否匹配所有元素
anyMatch :检查是否至少匹配一个元素
noneMatch :检查是否没有匹配的元素
findFirst :返回第一个元素
findAny :返回当前流中的任意元素
count :返回流中元素的总个数
max :返回流中最大值
min :返回流中最小值

forEach:内部迭代

5.2、 归约:(重点)

将流中元素反复结合起来,得到一个值。

reduce(T identity, BinaryOperator) 返回结果是T
reduce(BinaryOperator) 返回结果是Optional<T>

 @Testpublic void test1(){List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);//起始值是0,肯定不为空,所以返回值是IntegerInteger sum = list.stream().reduce(0, (x, y) -> x + y);System.out.println(sum);System.out.println("----------------------------------------");//因为没有起始值,所以返回值是 OptionalOptional<Double> op = emps.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println(op.get());}

5.3、收集:(重点)

将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法。

collect(Collector c)

Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例

 List<Employee> emps = Arrays.asList(new Employee(102, "李四", 79, 6666.66, Status.BUSY),new Employee(101, "张三", 18, 9999.99, Status.FREE),new Employee(103, "王五", 28, 3333.33, Status.VOCATION),new Employee(104, "赵六", 8, 7777.77, Status.BUSY),new Employee(104, "赵六", 8, 7777.77, Status.FREE),new Employee(104, "赵六", 8, 7777.77, Status.FREE),new Employee(105, "田七", 38, 5555.55, Status.BUSY));@Testpublic void test4(){// 最大值Optional<Double> max = emps.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));System.out.println(max.get());//最少的工资Optional<Employee> op = emps.stream().collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));System.out.println(op.get());//工资的总和Double sum = emps.stream().collect(Collectors.summingDouble(Employee::getSalary));System.out.println(sum);//工资的平均值Double avg = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));System.out.println(avg);// 总数Long count = emps.stream().collect(Collectors.counting());System.out.println(count);System.out.println("--------------------------------------------");DoubleSummaryStatistics dss = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));System.out.println(dss.getMax());}

5.4、分组

Collectors.groupingBy();

 //分组@Testpublic void test5(){Map<Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));System.out.println(map);}

运行结果:

{VOCATION=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], BUSY=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]], FREE=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]]}

多级分组:

 //多级分组@Testpublic 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 "中年";elsereturn "成年";})));System.out.println(map);}

运行结果:

{VOCATION={成年=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}, FREE={成年=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]]}, BUSY={成年=[Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY]], 老年=[Employee [id=102, name=李四, age=79, salary=6666.66, status=BUSY]], 中年=[Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}}

5.5、分区

Collectors.partitioningBy()

 @Testpublic void test7(){Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));System.out.println(map);}

5.6、前缀,后缀

Collectors.joining()

 @Testpublic void test8(){String str = emps.stream().map(Employee::getName).collect(Collectors.joining("," , "----", "----"));System.out.println(str);}

java8 —— Stream( 流 )相关推荐

  1. Java8——Stream流

    Java8--Stream流 Stream是数据渠道,用于操作集合.数组等生成的元素序列. Stream操作的三个步骤: 创建Stream 中间操作 终止操作 一.获取stream的四种方式 1.通过 ...

  2. java8 stream流 将一个list转换成list

    java8 stream流 将一个对象集合转换成另一个对象集合 案例一: // 利用stream进行类型转化     List<String> stringList = new Array ...

  3. Java8 Stream 流 一些使用整理(持续更新)

    Java8 Stream 流 一些使用整理 双循环判断值 原始写法 Stream 普通写法 Stream filter + anyMatch写法 持续更新中 双循环判断值 原始写法 List<C ...

  4. 学习Java8 Stream流,让我们更加便捷的操纵集合

    1. 概述 本篇文章会简略的介绍一下 Lambda 表达式,然后开启我们的正题 Java8 Stream 流,希望观众老爷们多多支持,并在评论区批评指正! Java8 的 Stream 流使用的是函数 ...

  5. java8 Stream流【华为3面】

    华为三面@java8 stream流操作面试题 前言:华为三面考了个很简单的基础编程,就是java8 Stream流操作,太久没写,也是没掌握好java基础直接搞得措手不及,stream两行代码的事情 ...

  6. Java8 Stream流递归,几行代码搞定遍历树形结构

    欢迎关注方志朋的博客,回复"666"获面试宝典 可能平常会遇到一些需求,比如构建菜单,构建树形结构,数据库一般就使用父id来表示,为了降低数据库的查询压力,我们可以使用Java8中 ...

  7. [转载] Java8 Stream流遍历 如何使用索引

    参考链接: Java 8中迭代带有索引的流Stream 1. 问题来源 Java8的Stream流为我们的遍历集合带来了方便,基本可以取代for循环了.但是有一些情况需要知道当前遍历的索引,使用for ...

  8. [编程] Java8 Stream(流式计算) 常见的一些用法汇总

    前提:以下基于 List<Student> 列表进行举例,大家实际使用进行举一反三即可.大同小异,Java8 的流式计算功能很强大,需要大家实际应用中逐渐挖掘更高级的用法. Student ...

  9. Java8 Stream流操作在用户系统中的妙用

    在做目前这个项目的时候,发现以前有一个筛选的需求,老程序员是这么做的,先请求Http服务器得到一长串json数据,大概用A4纸打了40多页那么多,然后将这些对象写入到sqlite数据库中,再用数据库查 ...

  10. java8 Stream流

    目录 前言 一.stream的使用场景特点 特点: 二.初步体验一下stream 三.简单看一下Stream的常用API 3.1 forEach()遍历集合中的对象 3.2filter对流对象进行过滤 ...

最新文章

  1. mysql 创建师徒_mysql基础整理
  2. 【转贴】Decoda Tutorial LUA调式器
  3. mysql筛选两个表有相同项的数据库_用SQL查询两个表中相同的数据
  4. mybatis主键生成策略和mp主键生成策略
  5. es6 Mixin 模式的实现
  6. win10 mysql5.7.21_win10下mysql5.7.21解压版安装教程
  7. Spring Cloud 服务消费者 Feign (三)
  8. 刷paper利器!不想打开PDF,这个插件自动帮你转到介绍页
  9. java实验报告的原理_JAVA实验报告
  10. Javascript之把网页加入收藏夹功能
  11. linux wr vi 命令,Linux下Vi命令详解
  12. 掩膜裁剪tif步骤_ENVI中掩膜掩膜操作及影像分类教程
  13. window7下visio 2013 64位激活工具
  14. 开发游戏十年,遭遇游戏开发史上最诡异事件,然而被我成功解决了!
  15. redis streams_如何使用Redis Streams
  16. 如何设置计算机桌面待办事项,怎么在Windows电脑桌面便签上显示未来要处理的待办事项?...
  17. 基于Linux操作系统的 智能家居的设计
  18. JavaScript之赛车游戏
  19. java 日食还是月蚀_你了解人们常说的日食与月食吗?
  20. 第七十篇:从ADAS到自动驾驶(三):车道检测

热门文章

  1. [Win32]鼠标的基本概念以及击中测试
  2. 浅谈XPS文件格式。
  3. Windows下MySQL8安装教程
  4. 六字诀教你辨肾脏是否健康
  5. Win10自带邮件系统绑定腾讯企业邮箱
  6. log4j日志输出性能优化-缓存、异步
  7. 数据库的行列互换问题
  8. GA(遗传算法) 解决TSP问题 Python实现
  9. DataX Transformer从入口到加载的源码分析及UDF扩展与使用
  10. Python实现数据保存为PSV文件(先创建CSV,转换成PSV)