文章目录

  • Stream API
    • Stream和Collection的区别
    • Stream操作的三个步骤
    • 创建Stream
      • 方法一:通过集合创建
      • 方法二:通过数组创建
      • 通过Stream类的静态方法 of创建
      • 方式四:无限流
    • 中间操作
      • 筛选与切片
      • 映射
      • 排序
    • 终止操作
      • 匹配与查找
      • 归约
      • 收集

Stream API

Stream API – > java.util.stream
Stream是java8中处理集合的关键抽象概念
可以执行非常复杂的查找、过滤和映射数据等操作
类似于使用SQL执行的数据库查询
Stream API提供了一种高效且易于使用的数据处理方式

Stream和Collection的区别

Collection是一种静态的内存数据,主要面向内存,存储在内存中
Stream与计算有关,主要面向CPU,通过CPU实现计算

注意:

  1. Stream 自己不会存储元素
  2. Stream 不会改变源对象。会返回一个持有结果的新Stream
  3. Stream 操作时延迟执行的,需要结果的时候才执行

Stream操作的三个步骤

  1. 创建Stream
    使用一个数据源(如:集合、数组),获取一个Stream流
  2. 中间操作(过滤、映射…)
    中间操作链,对数据源进行数据加工处理
  3. 终止操作(终端操作)
    一点执行终止操作,就执行中间操作链,并返回结果。之后,不会再被使用

创建Stream

方法一:通过集合创建

  1. 顺序流:按照集合中的顺序进行执行
// default Stream<E> stream();
List<Employee> employees = EmployeeData.getEmployees();
Stream<Employee> stream = employees.stream();
  1. 并行流
// default Stream<E> parallelStream()
List<Employee> employees = EmployeeData.getEmployees();
Stream<Employee> parallelStream = employees.parallelStream();

方法二:通过数组创建

// Arrays static <T> Stream<T> stream(T[] array)
Employee[] empArr = employees.toArray(new Employee[employees.size()]);
Stream<Employee> stream1 = Arrays.stream(empArr);
int[] iArr = {1,2,3};
IntStream intStream = Arrays.stream(iArr);

通过Stream类的静态方法 of创建

// static<T> Stream<T> of(T... values);
Stream<String> stringStream = Stream.of("1", "2", "3", "4");
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);

方式四:无限流

  1. 迭代:public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
  2. 生成:public static<T> Stream<T> generate(Supplier<T> s)
Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
Stream.generate(Math::random).limit(10).forEach(System.out::println);

中间操作

多个中间操作可以链接起形成一条,除非链上触发终止操作,否则中间操作不会执行任何处理,只有在终止操作时一次性全部处理,称为惰性求值

筛选与切片

方法 描述
filter(Predicate p) 接收Lambda,从流中排出某些元素
distinct() 筛选,通过流所生成元素的hashCode()equals()去除重复元素
limit(long maxSize) 截断流,使元素不超过给定数量
skip(long n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(long maxSize)互补
// filter(Predicate p) 接收Lambda,从流中排出某些元素
List<Employee> list = EmployeeData.getEmployees();
Stream<Employee> stream = list.stream();
// 查询员工薪资大于90000
stream.filter(e -> e.getSalary() > 90000).forEach(System.out::println);
System.out.println("******************************************************");
stream = list.stream();
// limit(long maxSize) 截断流,使元素不超过给定数量
stream.limit(3).forEach(System.out::println);
System.out.println("******************************************************");
// skip(long n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与 limit(long maxSize) 互补
list.stream().skip(5).forEach(System.out::println);
System.out.println("******************************************************");
// distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
list.add(new Employee(1009, "扎克伯格1", 28, 3422.34));
list.add(new Employee(1009, "扎克伯格1", 28, 3422.34));
list.add(new Employee(1009, "扎克伯格1", 28, 3422.34));
list.stream().distinct().forEach(System.out::println);

映射

方法 描述
map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素
mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的DoubleStream
mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的IntStream
mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的LongStream
flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
// 中间操作:映射
@Test
public void test3() {// map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素List<String> list = Arrays.asList(new String[]{"tom", "jerry"});list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);List<Employee> employeeList = EmployeeData.getEmployees();employeeList.stream().map(Employee::getName).filter(name -> name.length() > 3).forEach(System.out::println);System.out.println("########################################S");// flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流list.stream().map(StreamAPITest::stringToStream).forEach(s -> {s.forEach(System.out::println);});System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");list.stream().flatMap(StreamAPITest::stringToStream).forEach(System.out::println);
}public static Stream<Character> stringToStream(String str) {List<Character> list = new ArrayList<>();for (char c : str.toCharArray()) {list.add(c);}return list.stream();
}

排序

方法 描述
sorted() 自然排序
sorted(Comparator com) 按比较强顺序排序
// sorted() 自然排序
List<Integer> intList = Arrays.asList(2, 6, 2, 1, 7, 12, 45, 67);
intList.stream().sorted().forEach(System.out::println);
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// sorted(Comparator com) 按比较强顺序排序
List<Employee> list = EmployeeData.getEmployees();
list.stream().sorted((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())).forEach(System.out::println);

终止操作

会使流产生结果,其中的结果可以是任何不是流的值,如:List,Integer,void。流进行终止操作后,不能再次使用

匹配与查找

方法 描述
allMatch(Predicate p) 检查是否匹配到所有元素
anyMatch(Predicate p) 检查是否匹配到至少一个元素
noneMatch(Predicate p) 检查是否没有匹配到所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流中元素总数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
forEach(Consumer c) 内部迭代 ,使用Collection接口需要yoghurt去做的迭代叫外部迭代,StreamAPI使用内部迭代。也可以用Collection.forEach(Consumer c)做迭代
// 匹配与查找
@Test
public void test1() {// | allMatch(Predicate p) | 检查是否匹配到所有元素 |List<Employee> list = EmployeeData.getEmployees();boolean b = list.stream().allMatch(e -> e.getAge() >= 30);System.out.println(b);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | anyMatch(Predicate p) | 检查是否匹配到至少一个元素 |boolean b1 = list.stream().anyMatch(e -> e.getSalary() > 50000);System.out.println(b1);System.out.println("####################################################");// | noneMatch(Predicate p) | 检查是否没有匹配到所有元素 |boolean b2 = list.stream().noneMatch(e -> e.getName().contains("马"));System.out.println(b2);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@S");// | findFirst() | 返回第一个元素 |Optional<Employee> firstEmployee = list.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();System.out.println(firstEmployee);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | findAny() | 返回当前流中的任意元素 |Optional<Employee> anyEmployee = list.parallelStream().findAny();System.out.println(anyEmployee);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | count() | 返回流中元素总数 |long count = list.stream().count();System.out.println(count);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | max(Comparator c) | 返回流中最大值 | 注意,比较方法写反了,取得最小值// Optional<Employee> max = list.stream().max((e1, e2) -> Double.compare(e2.getSalary(), e1.getSalary()));Optional<Employee> max = list.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println("max:" + max);Optional<Double> maxSalary = list.stream().map(Employee::getSalary).max(Double::compare);System.out.println("maxSalary:" + maxSalary);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | min(Comparator c) | 返回流中最小值 |Optional<Employee> min = list.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));System.out.println(min);System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");// | forEach(Consumer c) | 内部迭代 |list.stream().forEach(System.out::println);
}

归约

方法 描述
reduce(T iden, BunaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b) 将流中元素反复结合,得到一个值。返回Optional<T>

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

// 归约
@Test
public void test3() {// | reduce(T iden, BunaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回T |List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);Integer reduce = list.stream().reduce(0, Integer::sum);System.out.println(reduce);// | reduce(BinaryOperator b) | 将流中元素反复结合,得到一个值。返回Optional\<T> |List<Employee> employeeList = EmployeeData.getEmployees();Optional<Double> reduce1 = employeeList.stream().map(Employee::getSalary).reduce(Double::sum);System.out.println(reduce1);
}

收集

方法 描述
collect(Collector c) 将流转换为其他形式。接收一个Collector接口的实现

Collector接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)

Collectors实现类提供了很多的静态方法,可以方便地创建常见收集器实例,方法见下表:

方法 返回类型 作用 示例
toList List<T> 把流中元素收集到List list.stream().collect(Collectors.toList())
toSet Set<T> 把流中元素收集到Set list.stream().collect(Collectors.toSet())
toCollection Collection<T> 把流中元素收集到创建的集合 list.stream().collect(Collectors.toCollection(ArrayList::new))
counting Long 计算流中元素个数 list.stream().collect(Collectors.counting())
summingInt Integer 对流中元素整数属性进行求和 list.stream().collect(Collectors.summingInt(Employee::getSalary))
averagingInt Integer 对流中Integer属性求平均值 list.stream().collect(Collectors.averagingInt(Employee::getAge))
summarizingInt IntSummaryStatics 收集流中Integer属性的统计值。如平均值 list.stream().collect(Collectors.summarizingInt(Employee::getAge))
joining String 连接流中每个字符串 list.stream().collect(Collectors.joining())
maxBy Optional<T> 根据比较器获取最大值 list.stream().collect(Collectors.maxBy(Employee::getSalary))
minBy Optional<T> 根据比较器获取最小值 list.stream().collect(Collectors.minBy(Employee::getSalary))
reducing 归约产生的类型 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值 list.stream().collect(Collectors.reducing(0, Employee::getSalary, Integer::sum))
collectIngAndThen 转换函数返回的类型 包裹另一个收集器,对其结果转换函数 list.stream().collect(Collectors.collectIngAndThen(Collectors.toList(), List::size))
groupingBy Map<k, List<T>> 根据某属性值对流分组,属性为K,结果为V list.stream().collect(Collectors.groupingBy(Employee::getStatus)
partitioningBy Map<Boolean, List<T>> 根据true或false进行分区 list.stream().collect(Collectors.partitioningBy(Employee::getManage)
// 收集
@Test
public void test4() {// | collect(Collector c) | 将流转换为其他形式。接收一个Collector接口的实现 |List<Employee> list = EmployeeData.getEmployees();List<Employee> collect = list.stream().filter(e -> e.getSalary() > 200000).collect(Collectors.toList());System.out.println(collect);System.out.println();// | toSet | Set\<T> | 把流中元素收集到Set| list.stream().collect(Collectors.toSet()) |Set<Employee> collect1 = list.stream().filter(e -> e.getSalary() > 200000).collect(Collectors.toSet());System.out.println(collect1);System.out.println();// | toCollection | Collection\<T> | 把流中元素收集到创建的集合| list.stream().collect(Collectors.toCollection(ArrayList::new)) |ArrayDeque<Employee> collect2 = list.stream().filter(e -> e.getSalary() > 200000).collect(Collectors.toCollection(ArrayDeque::new));System.out.println(collect2);System.out.println();// | counting | Long | 计算流中元素个数 | list.stream().collect(Collectors.counting()) |Long collect3 = list.stream().collect(Collectors.counting());System.out.println(collect3);// | summingInt | Integer | 对流中元素整数属性进行求和|list.stream().collect(Collectors.summingInt(Employee::getSalary)) |Integer collect4 = list.stream().collect(Collectors.summingInt(Employee::getAge));System.out.println(collect4);IntSummaryStatistics collect5 = list.stream().collect(Collectors.summarizingInt(Employee::getAge));System.out.println("collect5:" + collect5);}

java8(三)Stream API相关推荐

  1. 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!

    写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*)  ,那什么是Stream API呢?Java8中 ...

  2. Java8的Stream API使用(笔记)

    个人转载仅作为笔记使用,如有任何问题可以到原文链接探讨,原文连接为:https://www.cnblogs.com/jimoer/p/10995574.html 前言 这次想介绍一下Java Stre ...

  3. Java8的Stream API使用

    前言 这次想介绍一下Java Stream的API使用,最近在做一个新的项目,然后终于可以从老项目的祖传代码坑里跳出来了.项目用公司自己的框架搭建完成后,我就想着把JDK版本也升级一下吧(之前的项目, ...

  4. java8之Stream API(提取子流和组合流)

    为什么80%的码农都做不了架构师?>>>    Stream.limit(n)会返回一个包含n个元素的新流(如果原始流的长度小于n,则会返回原始的流).例如: package jav ...

  5. java8三次分组_Java8分组(groupingBy)

    1.分组,计数,排序 public class Java8Example1 { public static void main(String[] args) { List items = Arrays ...

  6. Java8 Lambda表达式(三)Lambda表达式与Stream API

    目录 1 Stream基本概念 1.1 什么是Stream 1.2 Stream的特点 2 Stream API初体验 2.1 构造数据 2.1 使用for循环实现 2.2 使用Lambda表达式结合 ...

  7. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

  8. 学习笔记之-java8的新特性-函数式接口,lambda表达式,方法引用,Stream API,Optional类

    1.Lambda表达式 用匿名内部类的方法去创建多线程1.new Thread2.参数传递new Runnable3.重写run方法4.在run方法中去设置线程任务5.调用start问题:我们最终目标 ...

  9. 【java8新特性】——Stream API详解(二)

    一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...

最新文章

  1. 软件行业项目经理主要的职责是什么?(转)
  2. python人工智能入门书籍推荐-小编就给大家推荐几本python机器学习入门书!
  3. JSP标准标签库JSTL总结
  4. 当adobe flash player不能安装时
  5. cocos ScrollView(滚动容器)加载大量item导致的卡顿问题解决方案
  6. 用户画像_什么是“用户画像”?如何利用用户画像进行精准营销?
  7. 日志服务与SIEM(如Splunk)集成方案实战 1
  8. SSH中设置字符编码防止乱码
  9. 芯片测试探针卡_测试接口业者先受惠苹果A14 GPU双雄4Q再加Socket、探针卡急单
  10. 新征程 linux下C编程
  11. 大觉寺到鹫峰线路_大觉寺到鹫峰怎么走
  12. 解决php截取文字乱码问题
  13. GAX (Guidance Automation Extensions) 与 GAT (Guidance Automation Toolkit)
  14. Android源码编译 首发ViVo Xplay X510w 2.14.8 完美root/美颜相机/状态栏美化/支持官方OTA/纯净,稳定ROM
  15. FreeBSD搭建Nginx+Apache24+php56+mysql56手把手一步步的笔记
  16. (十)损失函数与反向传播
  17. QT的QScrollArea使用详解
  18. 使用mysqldump+WinRAR压缩备份数据库
  19. Who is the lion(谁是狮子)!
  20. 【C++】9.GIS应用:开源GIS平台开发入门(MapServer+QGIS+PostGIS+OpenLayers)

热门文章

  1. JDBC--基础JDBC
  2. C-Kermit在linux 下的安装和使用
  3. 序列的算法(一·a)马尔可夫模型
  4. matlab求解微分方程解析解
  5. substance painter学习2——新建项目
  6. 论文写作 18: 审稿意见回复要直截了当
  7. 《阿里巴巴java规范》 Result 方式杂谈
  8. pr学习日记①初接触
  9. java float类型是否为空_java – 如何使float类型的变量为null
  10. 如何加密/弄乱C源代码