Java8—Stream API

文章目录

  • 前言
  • 什么是流
    • 感性的认识一下流
    • 只能遍历一次
  • 流的使用
    • 中间操作
      • filter
      • distinct
      • limit
      • skip
      • map
      • flatMap
      • 查找与匹配:allMatch、anyMatch、noneMatch、findFirst和findAny
    • 终端操作
      • 归约:reduce
      • 预定义收集器
    • 小结
  • 构建流

前言

如果说Lambda只是一些表达形式上的奇技淫巧,那么结合Java8的Stream API,我们就会发现什么才是功能强大的代码。

表达简单,功能强大。让人想的多,写的少。

什么是流

流是一系列元素的集合,

但是,与集合不同的是,集合中的元素在一开始就已经在内存中了,而流中的元素是一个个取出来的

操作流的时候的感觉,特别像是在操作SQL中的集合

只要选择合适的流操作方法,然后将逻辑传递进去即可

流与集合,其实是一个时间与空间上的区分,流用时间来换取空间

感性的认识一下流

就问你DBD,上述逻辑,使用SQL也就是一句话的事儿,但是如果是Java8以前,那就得写一大段代码。

  • filter

接收Lambda,从流中排除某些元素

  • map

接收Lambda,将元素转化成其他形式

  • collect

将流转化为其他形式

只能遍历一次

一个流被创建后,就只能遍历一次,如果想再次遍历,就得重新创建流

        List<Apple> apples = MainPart01.createApples();
        apples.stream()
                .forEach(apple -> {
                    System.out.println(apple);
                });

流的使用

中间操作

流的中间操作,其返回仍旧是一个流,可以被后续继续处理

filter

对元素进行boolean判断,不符合要求的会从流中剔除出去

一般用方法引用作为参数更方便

distinct

剔除掉重复的元素,所谓重复,是通过元素的equals和hashCode判断的

limit

截取流的前n的元素,后续元素丢弃

skip

跳过指定个数的元素

map

将当前流中的元素映射成另一种元素类型

之所以叫映射,而不是转化,是因为map操作不改变原先流中的元素

flatMap

流的扁平化

一言以蔽之,flatmap方法让你把一个流中的每个值都换成另一个流,然后把所有的流连接 起来成为一个流

查找与匹配:allMatch、anyMatch、noneMatch、findFirst和findAny

终端操作

流的终端操作,是将流转化成结果

归约:reduce

  • 求和

int sum = numbers.stream().reduce(0, (a, b) -> a + b);

int sum = numbers.stream().reduce(0, Integer::sum);

  • 乘积

int product = numbers.stream().reduce(1, (a, b) -> a * b);

  • 最值

Optional max = numbers.stream().reduce(Integer::max);

所谓归约,就是将流归约为一个值

怎样用map和reduce方法数一数流中有多少个菜呢?
答案:要解决这个问题,你可以把流中每个元素都映射成数字1,
然后用reduce求和。这相当于按顺序数流中的元素个数。

    int count = menu.stream()
                    .map(d -> 1)
                    .reduce(0, (a, b) -> a + b);

预定义收集器

Collectors类提供的工厂方法

它们主要提供了三大功能:

  • 将流元素归约和汇总为一个值
  • 元素分组
  • 元素分区

下面就对预定义收集器中的内容挑几个讲讲

Collectors.counting

long howManyDishes = menu.stream().collect(Collectors.counting());
这还可以写得更为直接:
long howManyDishes = menu.stream().count(); 
counting收集器在和其他收集器联合使用的时候特别有用,后面会谈到这一点。
在本章后面的部分,我们假定你已导入了Collectors类的所有静态工厂方法: 
import static java.util.stream.Collectors.*;
这样你就可以写counting()而用不着写Collectors.counting()之类的了。

Collectors.maxBy和 Collectors.minBy

汇总

字符串连接

String shortMenu = menu.stream().map(Dish::getName).collect(joining());

分组

多级分组


小结

构建流

  • 由值创建

Stream stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");

  • 由数组创建
int[] numbers = {2, 3, 5, 7, 11, 13}; 
int sum = Arrays.stream(numbers).sum()
  • 由文件生成

  • 无限流
Stream.iterate(0, n -> n + 2)
      .limit(10)
      .forEach(System.out::println);

按照自己的规则生成流

Stream.generate(Math::random)
          .limit(5)
          .forEach(System.out::println);

你可能感兴趣的:(Java8—Stream API)