java8除了提供了Lambda表达式,操作集合的Stream API也是新特性中最值得学习和掌握的,它大大简化了,我们操作数据集合的代码量的书写。简单来说Stream是一个抽象概念,可以通过查找,过滤,映射等操作,这一点与Scala中集合操作很类似。

Stream是什么

通俗的说就是操作数据集合的一种手段,你可以使用它,以获取所需要的集合数据源类型,如下图所示:
通常Stream流操作整个流程是创建流对象->对流操作->获得目标数据源操作

创建Stream

  • 通过Collection接口提供的Stream

    • 返回一个顺序流

      default Stream<E> stream() {return StreamSupport.stream(spliterator(), false);}
      
    • 返回一个并行流

      default Stream<E> parallelStream() {return StreamSupport.stream(spliterator(), true);
      }
      
    • 两种流的使用

      package com.codegeek.lambda;
      import lombok.*;@Setter
      @Getter
      @NoArgsConstructor
      @ToString
      public class Employee {/*** 员工姓名*/private String name;/*** 员工年龄*/private int age;/*** 基本薪水*/private double basicSalary;/*** 订单成交总额*/private double dealTotalPrice;public Employee(String name, int age, double basicSalary,double dealTotalPrice) {this.name = name;this.age = age;this.basicSalary = basicSalary;this.dealTotalPrice = dealTotalPrice;}/*** 员工总薪资=基本薪资+提成薪资** @return Double*/public Double getTotalSalary() {return this.basicSalary + this.dealTotalPrice * 0.04;}
      }
      

      测试方法:

       @Testpublic void test() {Employee qingLong = new Employee("青龙", 25, 5500, 7500);Employee baiHu = new Employee("白虎", 27, 5000, 9000);Employee zhuQue = new Employee("朱雀", 22, 3800, 4500);Employee xuanWu = new Employee("玄武", 24, 3300, 3300);List<Employee> employees = Arrays.asList(qingLong, baiHu, zhuQue, xuanWu);// 得到一个顺序流,并获取工资大与4000的员工的姓名Stream<Employee> stream = employees.stream();stream.filter(e-> e.getTotalSalary()>4000).map(Employee::getName).forEach(System.out::println); // 得到一个并行流,获取年龄大于25的员工姓名Stream<Employee> employeeStream = employees.parallelStream();employeeStream.filter(employee -> employee.getAge()> 25).map(Employee::getName).forEach(System.out::println );
      }
      
  • 通过Arrays创建Stream流

注意数组里面是什么类型的数组,就会产生同类型的流。

// 例子
// 初始化一个数组对象int[] arr = {11, 55, 44, 20, 45, 16};
// 通过Arrays创建流对象是IntStreamArrays.stream(arr).sorted().forEach(System.out::println);

Stream常见的操作

过滤和切片

方法 方法介绍
filter(Predicate<? super T> predicate) 接收断言接口,并从流中排除元素
distinct() 去除流中重复的元素
limit(long maxSize) 截取流中元素个数,类似sql查询limit
skip(long n) 跳过元素,跳过前n个元素
@Test
public void testFilter() {int[] age = {11, 22, 44, 22, 24, 24, 66, 77, 77, 25, 34};// 使用filter过滤获得大于33的数组元素Arrays.stream(age).filter(i -> i > 33).forEach(System.out::println);// 去重Arrays.stream(age).distinct().forEach(System.out::println);// 截取3个元素Arrays.stream(age).limit(3).forEach(System.out::println);// 跳过前3个元素Arrays.stream(age).skip(3).forEach(System.out::println);
}

映射

方法 方法介绍
map(Function mapper) 接收一个函数式接口,将会映射到流中的每一个元素
mapToDouble(ToDoubleFunction mapper) 接收函数式接口,将映射产生DoubleStream
mapToLong(ToLongFunction mapper) 接收函数式接口,将映射产生LongStream
mapToInt(ToIntFunction mapper) 接收函数式接口,将映射产生IntStream
flatMap(Function extends Stream mapper) 接收函数,将流中的每个值都转换一个流,然后将这些流汇成一个流
String[] arr = {"java", "scala", "php", "python", "c++"};
// 将流中的每一个元素转换成大写
Arrays.stream(arr).map(String::toUpperCase).forEach(System.out::println);
//将流中的数据转Double类型
long[] array = {1, 4, 6, 7, 12};
// 返回Double类型的Stream
Arrays.stream(array).mapToDouble(e-> e* 100).forEach(System.out::println);
// 返回Long类型的Stream
Arrays.stream(array).mapToLong(e -> e + 23).forEach(System.out::println);
// flatMap演示
List<List<String>> database = new ArrayList<>();
List<String> noSql = Arrays.asList("redis", "hbase", "membercache");
List<String> sql = Arrays.asList("mysql", "oracle", "db2");
database.add(noSql);
database.add(sql);
List<String> h = database.stream().flatMap(s -> s.stream().filter(si -> si.contains("h"))).collect(Collectors.toList());
h.stream().forEach(System.out::println);

排序

Employee qingLong = new Employee("青龙", 25, 5500, 7500);
Employee baiHu = new Employee("白虎", 27, 5000, 9000);
Employee zhuQue = new Employee("朱雀", 22, 3800, 4500);
Employee xuanWu = new Employee("玄武", 24, 3300, 3300);
List<Employee> employees = Arrays.asList(qingLong, baiHu, zhuQue, xuanWu);
// 按照薪水的大小进行排序
employees.stream().sorted(Comparator.comparing(Employee::getTotalSalary)).forEach(System.out::println);

查找与匹配

方法 方法介绍
allMatch(Predicate p) 检查流中的元素是否都匹配
anyMatch(Predicate p) 检查是否匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回流中任意元素
count 返回流中的个数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
// 判断所有的员工年龄是否大于18
boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
System.out.println("allMatch="+b);// 结果为true
// 判断所有员工中有没有年龄大于35的
boolean b1 = employees.stream().anyMatch(e -> e.getAge() > 35);
System.out.println("anyMath=" + b1); // 结果为false
// 判断所有员工中没有年龄大于35的
boolean b1 = employees.stream().noneMatch(e -> e.getAge() > 35);
System.out.println("anyMath=" + b1); // 结果为true
// 返回第一个员工的信息
Optional<Employee> first = employees.stream().findFirst();
System.out.println(first.get());
// 统计年龄大于20的员工个数
ong count = employees.stream().filter(e -> e.getAge() > 20).count();
System.out.println("count="+count);
// 统计集合中员工薪资最高的员工信息
Optional<Employee> max = employees.stream().max(Comparator.comparing(Employee::getTotalSalary));
System.out.println("max=" + max);

归约

方法 方法介绍
reduce(BinaryOperator p) 将流中的元素反复结合起来得到一个值返回Optional
reduce(T iden,BinaryOperator p) 将流中的元素反复结合起来得到一个值T
Optional<Double> reduce = employees.stream().map(Employee::getTotalSalary).reduce(Double::sum);
double v = reduce.get();
System.out.println("reduce="+v);
int[] array = {1, 4, 6, 7, 12};
System.out.println("====");
// 这里第一次将0作为x的值然后数组中1作为y,然后计算后的结果是1,第二次将1作为x的值,然后数组中的4作为y值进行相加,后面以此类推,直到将所有的值都进行相加
int reduce = Arrays.stream(array).reduce(0, (x, y) -> x + y);
System.out.println("reduce=" + reduce);

收集

方法 方法介绍
collect(Collector c) 将流转换为其他形式,接收Collector接口实现。
@Testpublic void test() {// 收集获取总数(集合总数)Long collect = employees.stream().collect(Collectors.counting());System.out.println(collect);// 工资的平均值Double collect1 = employees.stream().collect(Collectors.averagingDouble(Employee::getTotalSalary));System.out.println(collect1);// 获取工资的总数,综合,最小值,平均值,最大值DoubleSummaryStatistics collect2 = employees.stream().collect(Collectors.summarizingDouble(Employee::getTotalSalary));System.out.println(collect2);// 获取年龄最大的员工Optional<Employee> collect3 = employees.stream().collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));System.out.println(collect3.get());// 获取年龄最小的员工Optional<Double> collect4 = employees.stream().map(Employee::getTotalSalary).collect(Collectors.minBy(Double::compare));System.out.println(collect4.get());// 按薪资分组Map<Double, List<Employee>> collect5 = employees.stream().collect(Collectors.groupingBy(Employee::getTotalSalary));System.out.println(collect5);// 薪资分区(匹配true)Map<Boolean, List<Employee>> collect6 = employees.stream().collect(Collectors.partitioningBy((e) -> e.getTotalSalary() > 5000d));System.out.println(collect6);}

java8新特性-stream学习相关推荐

  1. Java8新特性Stream流详解

    陈老老老板 说明:新的专栏,本专栏专门讲Java8新特性,把平时遇到的问题与Java8的写法进行总结,需要注意的地方都标红了,一起加油. 本文是介绍Java8新特性Stream流常用方法超详细教学 说 ...

  2. java8新特性-stream对map集合进行过滤的方法

    java8新特性-stream对map集合进行过滤的方法 stream对map集合进行过滤的方法

  3. List 集合去重方式与 java8新特性stream去重

    以下介绍五种 - 不同的方法去除 Java 中 ArrayList 中的重复数据 1.使用 LinkedHashSet 删除 arraylist 中的重复数据 LinkedHashSet 是在一个 A ...

  4. java8新特性-Stream入门学习

    上一篇介绍了Lambda的学习,如果对Lambda表达式还不清晰的同学可以戳一下这个链接:java8新特性-lambda表达式入门学习.java8除了提供了Lambda表达式,操作集合的Stream ...

  5. java8新特性stream流

    参考自深蓝至尊的Java8 新特性之流式数据处理 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式 ...

  6. Java基础学习总结(55)——java8新特性:stream

    java作为开发语言中的元老已经度过了很多年,最新的java8为我们带来了一些新特性,这些特性可以在以后的工作中为我们的开发提供更多的便捷,现在就让我们看看最新的函数式编程风格怎么在实际的开发中使用.

  7. 【Stream】java8新特性Stream流总结

    一.什么是stream 在 java8 中增加了一个新的抽象接口 Stream API,使用 Stream 操作集合类似于使用 SQL 语句数据库查找数据类似,提供直观的方法进行操作. Stream ...

  8. 夯实基础,Java8新特性Stream详细教程

    1 基本特性 Java8的API中添加了一个新的特性: 流,即stream.stream是将数组或者集合的元素视为流,流在管道中流动过程中,对数据进行筛选.排序和其他操作. 1.1 流的特性 stre ...

  9. Java8新特性 - Stream - 13 - Stream的max()、min()方法详解

    1.方法介绍 [方法签名]1.Optional<T> max(Comparator<? super T> comparator);2.Optional<T> min ...

最新文章

  1. 用JavaScript创建神经网络的有趣教程,一定要让你知道!
  2. HDU1527(博弈论)
  3. 复旦大学跑步爱好者协会章程(终稿)
  4. 将DevExpress.Utils.ImageCollection变量的image导出
  5. 16位汇编 在代码段中使用数据
  6. 音视频技术开发周刊 | 172
  7. P1021 邮票面值设计
  8. 性能测试基本流程介绍(《软件性能测试过程详解与安全剖析》)
  9. util中注入service
  10. C/C++只做经典编程语言
  11. cURL 原作者收到死亡恐吓邮件!
  12. 2018山东冬令营:UPC 计数问题 (二维树状数组)
  13. android bin目录是什么,android bin目录下的.ap_是神马文件?
  14. java虚拟机-d参数配置_JVM虚拟机参数介绍
  15. 第六节课-(第七节课)训练神经网络-2
  16. linux下通过V4L2驱动USB摄像头
  17. html表格中怎么将背景颜色虚化,如何在Photoshop中制作效果惊艳模糊背景!
  18. 语音智能时代,我选择这个浪尖
  19. SpringMVC基础学习之Controller的两种实现方式和RequstMapping注解的使用
  20. ESXI提示 ramdisk“tmp”已满的解决方案

热门文章

  1. python pyplot画图_matplotlib绘图——再谈axes和pyplot方法
  2. 「github资料」40个Python可视化图表案例(附零基础学习资料)篇幅较长,建议收藏
  3. 齐治堡垒机配置文件服务器,登录齐治堡垒机简易使用手册V
  4. 《AlwaysRun!》第七次作业:团队项目设计完善编码
  5. 标签打印软件如何制作检验标签
  6. 青蛙为什么要跳台阶,C语言趣解青蛙跳台阶问题
  7. 圆锥曲线条件4a3+27b2 !=0
  8. 【职场】辞职的时间节点有讲究,你知道吗?
  9. STM32使用HAL库,整体结构和函数原理介绍
  10. java毕业设计离散制造业产品销售管理系统(附源码、数据库)