Java8 Stream 基础

2022-08-19  本文已影响0人  Tinyspot

1. 流(Stream)

1.1 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. 惰性中间方法

3.1 filter(...)

list.stream()
        .filter(str -> {
            System.out.println("filter run....");
            return str.equals("111");
        });
        // .forEach(System.out::println);
// 不加 forEach(), filter() 里的内容不会执行

3.2 map(...)

3.3 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. 终止方法

4.1 collect

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

4.2 reduce(...)

// 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

上一篇 下一篇

猜你喜欢

热点阅读