Java 流API

2021-11-30 14:16 更新

Java流 - Java流API


流相关的接口和类在java.util.stream包中。

AutoCloseable接口来自java.lang包。

所有流接口从继承自AutoCloseable接口的BaseStream接口继承。

AutoCloseable
 |
 +--BaseStream
     |
     +--IntStream
     |
     +--LongStream
     |
     +--DoubleStream
     |
     +--Stream<T>

如果流使用集合作为其数据源,并且集合不需要关闭。

如果流基于可关闭的数据源(例如文件I/O通道),那么我们可以使用try-with-resources语句创建流,以使其自动关闭。


BaseStream

BaseStream接口定义所有类型的流的所有方法。

  • Iterator<T> iterator()
    终端操作
    返回流的迭代器。
  • sequential()
    中间操作
    返回顺序流。 如果流已经是顺序的,则它返回自身。 它将并行流转换为顺序流。
  • parallel()
    中间操作
    返回并行流。 如果流已经是并行的,则它返回自身。 它将顺序流转换为并行流。
  • boolean isParallel()
    如果流是并行,则返回true,否则返回false。
    在调用终端流操作方法后调用此方法可能会产生不可预测的结果。
  • unordered()
    中间操作
    返回流的无序版本。 如果流已经是无序的,则它返回自身。

Stream<T> 接口表示元素类型T的流。

流<Student> 表示学生对象流。

Stream <T>接口包含诸如filter(),map(),reduce(),collect(),max(),min()等。

当使用原始类型时,我们可以使用三个专门的流接口,称为IntStream,LongStream和DoubleStream。

这些接口提供了处理原始值的方法。

对于其他基本类型,例如float,short,byte,我们仍然可以使用三个专用流接口。

在下面的代码中,我们将使用stream来计算列表中所有奇整数的平方和。

我们将使用以下步骤进行计算。

创建流

Collection接口中的stream()方法返回一个顺序流。 这样,集合充当数据源。

下面的代码创建一个List <Integer>并从列表中获取一个Stream <Integer>

List<Integer>  numbersList = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> numbersStream  = numbersList.stream();

过滤流

如果指定的谓词对于该元素返回真,Stream<T> filter()使用Predicate<T>来保留元素。

以下语句获取仅奇数整数的流:

Stream< Integer> oddNumbersStream = numbersStream.filter(n - > n%2 == 1);

映射流

Stream< T> map()使用一个Function来映射每个元素在流中创建新流。

以下语句将流映射到其正方形:

Stream<Integer> aStream = stream.map(n -> n * n);

Reduce流

reduce(T identity,BinaryOperator<T>累加器)将流减少到单个值。

它采用一个初始值和一个 BinaryOperator<T> 作为参数的累加器。

reduce(T identity,BinaryOperator< T>累加器)使用所提供的初始值和关联累积函数对该流的元素执行减少,并返回减小的值。

这相当于:

T result = identity;
for (T element : this stream)
  result = accumulator.apply(result, element)
return result;

以下代码将流中的所有整数相加。

int sum = aStream.reduce(0, (n1, n2) -> n1 + n2);

Integer.sum()方法执行两个整数的和。

我们可以使用方法引用重写代码。

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

Together

以下代码将每个步骤链接在一起。

import java.util.Arrays;
import java.util.List;

public class Main {
  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    int sum = numbers.stream()
        .filter(n -> n % 2  == 1)
        .map(n  -> n * n)
        .reduce(0, Integer::sum);

    System.out.println(sum);
  }
}

上面的代码生成以下结果。

有序流与无序流

流可以是有序的或无序的。

有序流保持其元素的顺序。

Streams API可以将有序流(其可以表示有序数据源,例如列表或有序集)转换成无序流。

我们还可以通过应用排序中间操作将无序流转换为有序流。

import java.util.Arrays;
import java.util.List;

public class Main {
  public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(3,7,9,3,1,2,1, 2, 3, 4, 5);
    numbers.stream()
        .filter(n -> n % 2  == 1)
        .sorted()
        .forEach(System.out::println);
  }
}

上面的代码生成以下结果。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号