美文网首页
Java8 Stream 基础

Java8 Stream 基础

作者: Tinyspot | 来源:发表于2022-08-19 07:38 被阅读0次

1. 流(Stream)

  • 流(Stream)中保存对集合或数组数据的操作。和集合类似,但集合中保存的是数据
  • 流到底是什么?简短的定义就是“从支持数据处理操作的源生成的元素序列”
  • 类似于生活中的流水线

1.1 Stream 特点

  • Stream 自己不会存储元素
  • Stream 不会改变源对象。相反,它们会返回一个持有结果的新 Stream
  • Stream 操作是延迟执行的,这意味着它们会等到需要结果的时候才执行

优点:

  • 声明性—更简洁,更易读;
  • 可复合—更灵活;
  • 可并行——性能更好

for-each 外部迭代;Stream库使用内部迭代
和迭代器类似,流只能遍历一次
管道( | ) 一个程序的输出流作为另一个程序的输入流

1.2 Stream 使用步骤

  1. 构建流:创建一个流
  2. 中间操作:在一个或多个步骤中,将初始 Stream 转化到另一个 Stream 的中间操作
  3. 终止操作:使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行,在这之后,该 Steam 就不能使用了

使用链接方法(chaining):
可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作

1.3 三类接口

  • 中间方法:将流转换为另一个流
  • 终止方法:返回结果或执行操作,在执行方法终止后,流会自动关闭
  • 静态方法:创建一个流

2. 构建流

public interface Stream<T> extends BaseStream<T, Stream<T>> {
    public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {}
    public static<T> Stream<T> generate(Supplier<T> s) {}
}

示例:

  List<String> list = new ArrayList<>();
  list.add("aaa");
  Stream<String> stream = list.stream();
  Stream<String> parallelStream = list.parallelStream();

  // Arrays.stream
  String[] arr = {"aaa", "bbb"};
  Stream<String> stream = Arrays.stream(arr);
  stream.forEach(System.out::println);

2.2 迭代流

无限流 iterate(...) 接受一个初始值,还有一个依次应用在每个产生的新值上的 Lambda UnaryOperator<T>类型

  Stream<Integer> iterate = Stream.iterate(0, n -> n + 2);
  // limit(...)中间操作,限制下数量,不然会一直迭代
  iterate.limit(10).forEach(System.out::println);

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

2.4 生成流

generate(...) 不是依次对每个新生成的值应用函数的。它接受一个Supplier<T>类型的Lambda提供新的值

  Stream<Integer> generate = Stream.generate(() -> new Random().nextInt());
  generate.limit(5).forEach(System.out::println);

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

2.5 IntStream / LongStream / DoubleStream

range(...) / rangeClosed(...)

IntStream intStream = IntStream.rangeClosed(0, 10);
intStream.forEach(System.out::println);

3. 惰性中间方法

  • 流是惰性的,仅仅当终止操作开始时才会进行计算
  • filter, distinct, sorted
  • limit(n) 截断流;skip(n) 返回一个扔掉了前n个元素的流
  • map, flatMap, mapToInt
  • sorted

3.1 filter(...)

  • Stream<T> filter(Predicate<? super T> predicate)
  • filter(Predicate) 接受一个谓词作为参数,并返回一个包括所有符合谓词的元素的流
list.stream()
        .filter(str -> {
            System.out.println("filter run....");
            return str.equals("111");
        });
        // .forEach(System.out::println);
// 不加 forEach(), filter() 里的内容不会执行

3.2 map(...)

  • <R> Stream<R> map(Function<? super T, ? extends R> mapper);
  • map(Function<T, R>) 接受一个函数作为参数,这个函数会被应用到每个元素上,并将其映射成一个新的元素

3.3 flatMap

  • 流的扁平化
  • flatMap(Arrays::stream) 生成的单个流都被合并起来,即扁平化为一个流
  • flatMap() 把一个流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流
flatMap(Function<? super List<Child>, ? extends Stream<? extends R>> mapper)
// .flatMap(Collection::stream)

flatMap(Function<? super String[], ? extends Stream<? extends R>> mapper)
// .flatMap(Arrays::stream)
    List<String> words = Arrays.asList("hello", "world");
    List<String> collect = words.stream().distinct().collect(Collectors.toList());

    List<String> list = words.stream()
            .map(str -> str.split("")) // Stream<String[]>
            .flatMap(Arrays::stream) // Stream<String>
            .distinct()
            .collect(Collectors.toList());
    System.out.println(list);
    Student student = new Student();
    Student student2 = new Student();
    List<Student> students = Arrays.asList(student, student2);
    List<Child> childList = students.stream() // Stream<Student>
            .map(Student::getChilds) // Stream<List<Child>>
            .flatMap(Collection::stream) // Stream<Child>
            .collect(Collectors.toList());

    Stream<List<Child>> listStream = students.stream().map(Student::getChilds);
    Stream<Child> childStream = students.stream().map(Student::getChilds).flatMap(Collection::stream);
    Stream<Child> childStream2 = students.stream().map(Student::getChilds).flatMap(childs -> childs.stream());

public class Student {
  List<Child> childs;
}

4. 终止方法

  • void forEach(Consumer<? super T> action)
  • collect
  • max, min, count, sum, average
  • reduce
  • findFirst, firstAny, anyMatch, allmatch, noneMath, toArray

4.1 collect

List<String> aaa = list.stream().filter(str -> str.equals("aaa")).collect(Collectors.toList());

4.2 reduce(...)

  • 归约操作:将流中的元素规约为单一值(通过重复应用二元运算符)
  • Stream.reduce(T identity, BinaryOperator<T> accumulator)
// map 和 reduce 的连接通常称为 map-reduce 模式
Optional<Integer> reduce = list.stream()
                            .map(OrderDO::getId)
                            .reduce(Integer::sum);
// Integer.sum(int a, int b)
public static int sum(int a, int b) {
  return a + b;
}

Optional<Integer> count = list.stream()
                  .map(OrderDO::getId)
                  .reduce((a, b) -> a + b);

Reference

  • 《Java 实战》
  • 尚硅谷Java8新特性-李贺飞

相关文章

  • Java8之Stream流(六)收集

    Java8之Stream流(一)基础体验 Java8之Stream流(二)关键知识点 Java8之Stream...

  • Java 8 Stream--开发手册

    什么是Java8 Stream,为什么需要Stream? Stream是Java8一大亮点,它与 java.io ...

  • Java8 学习笔记

    @(in action系列)[java8, lambda, stream] Java8 学习 java8 能高效的...

  • Stream流

    Stream流 java8新特性 Stream定义 A sequence of elements supporti...

  • java8 stream lambda

    记录Java8的stream操作,供自己复习。 创建Stream Employee类 创建stream方法 for...

  • 网页收藏

    一. Java基础 Java8 Stream API使用 Lambda 表达式3.Optional3.你真的会写J...

  • JAVA8中Stream学习

    JAVA8中Stream学习 最近看了下Stream的api: Stream用户操作Collection族的数据,...

  • Java8 Stream 流的重用

    Java8 Stream 已经被操作或关闭 引言 在 java8 中,Stream 不能被重用,一旦它被使用或使用...

  • Java8 Stream 基础

    1. 流(Stream) 流(Stream)中保存对集合或数组数据的操作。和集合类似,但集合中保存的是数据 流到底...

  • Java8新特性(二)-Lambda表达式和函数式接口

    1. Lambda java8开始引入了Lambda表达式.lambda表达式是Stream API编程的基础。本...

网友评论

      本文标题:Java8 Stream 基础

      本文链接:https://www.haomeiwen.com/subject/ujntgrtx.html