Java 8 流 API

原文:https://www.studytonight.com/java-8/java-8-stream-api

Java Stream是 Java 8 版本中加入的一个新概念,它允许我们对元素流执行函数式操作,比如集合上的 map-reduce 转换。

Java 增加了一个新的包 java.util.stream ,它由几个类、接口组成,用于执行基于流的操作。

Java 流是一个能够执行其元素内部操作的组件。例如,它可以自己迭代它的元素。

流操作分为中间操作和终端操作。流源可以是集合、数组、生成器函数或输入/输出通道。

中间操作是懒操作,返回新的流。例如,执行诸如filter()的中间操作实际上并不执行任何过滤,而是创建一个新的流。

终端操作执行操作后终止流源管道。例如,Stream.forEachIntStream.sum可以遍历流以产生结果。

河流的特征

本质上是功能性的

流本质上是功能性的,它允许我们执行功能性风格的操作。对流的操作会产生结果,但不会修改其源。例如,过滤从集合中获得的流会生成一个没有过滤元素的新流,而不是从源集合中移除元素。

寻懒

Stream 使用惰性加载来提高性能。我们可以在许多流操作中使用延迟加载,如过滤、映射或重复删除等。流中间操作总是懒惰的。

无储存

流不是存储元素的数据结构,但它通过计算操作的管道传递来自源(如集合、数组或生成器函数)的元素。

可能无界

虽然 Java 集合的大小是有限的,但是流不需要。limit(n)或 findFirst()等短路操作可以允许在有限时间内完成对无限流的计算。

消耗品

在流的生命周期中,流的元素只被访问一次。再次重用流引用不起作用。我们需要创建一个新的流来重新访问源的相同元素。

如何创建流?

在集合中,我们可以通过stream()parallelStream()方法创建流,并通过Arrays.stream(Object[])方法从数组中创建流。我们将在这里看到创建流的实际例子。

Java.util.stream 的接口

以下是 java.util.stream 包的接口。我们可以在各种编程场景中使用这些来获取流。

|

连接

|

描述

| | 基流〔t0〕 | 它是流的基本接口,流是支持顺序和并行聚合操作的元素序列。 | | 收集器 | 一种可变的约简操作,将输入元素累积到可变的结果容器中,在处理完所有输入元素后,可选地将累积的结果转换为最终表示。 | | 双流 | 支持顺序和并行聚合操作的原始双值元素序列。 | | DoubleStream。建设者 | 双流的可变生成器。 | | IntStream | 支持顺序和并行聚合操作的一系列原始 int 值元素。 | | IntStream(串流)。Builder(构建器) | IntStream 的可变生成器。 | | 软件复读机 | 支持顺序和并行聚合操作的原始长值元素序列。 | | LongStream。建设者 | 长流的可变构建器。 | | 流 | 支持顺序和并行聚合操作的元素序列。 | | 小溪。建筑商 | 流的可变构建器。 |

Java.util.stream 的类

以下是 java.util.stream 包的类。我们可以使用这些类来收集中间数据和操作流。

| 班级 | 描述 | | 收集者 | 实现各种有用的约简操作的收集器的实现,例如将元素累积到集合中,根据各种标准汇总元素等。 | | StreamSupport | 用于创建和操作流的低级实用方法。 |

举例时间:

让我们举一个从列表创建流的例子。在这里,我们将所有列表元素转换成小写,并使用forEach()方法进行迭代。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<String> fruits = new ArrayList<String>();

        fruits.add("APPLE");
        fruits.add("BANANA");
        fruits.add("CHERRY");

        Stream<String> stream = fruits.stream();

        Stream<String> stringStream =
            stream.map((value) -> { return value.toLowerCase(); });
        stringStream.forEach(System.out::println);
    }
}

苹果 香蕉 樱桃

示例:筛选列表元素

我们可以使用流来过滤集合元素。在这里,我们使用filter()方法,并收集结果作为列表。filter()方法将 lambda 表达式作为参数。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);

        List<Integer> newlist =numbers.stream()  
                                      .filter(n->n>110)
                                      .collect(Collectors.toList());
        System.out.println(newlist);  
    }
}

【120,150】

示例:迭代元素

在流中遍历集合元素非常容易。我们只需要调用forEach()方法,得到遍历的所有元素。看,我们在 forEach()方法中传递了一个方法引用来PrintStream结果。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        Stream<Integer> stream = numbers.stream();
        stream.forEach(System.out::println); 
    }
}

100 110 120 150

示例:最小值和最大值

如果我们想获得集合的最小值或最大值,那么通过使用流,我们可以很容易地做到这一点。这里,我们使用min()max()方法从流中获取结果。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        Stream<Integer> stream = numbers.stream();
        int max_val = stream.max((x,y)->x>y?1:-1).get();
        System.out.println("Max Value : "+max_val);
        int min_val = numbers.stream().min((x,y)->x<y?-1:1).get();
        System.out.println("Min Value : "+min_val);

    }
}

最大值:150 最小值:100

示例:使用 reduce()方法求和

reduce()是一种将流中的元素简化为单个元素的方法,可用于获取所有元素的总和。见下面的例子。

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        System.out.println(numbers);
        Stream<Integer> stream = numbers.stream();
        Optional<Integer> sum = stream.reduce(Integer::sum); 
        System.out.println("Sum = "+sum.get());

    }
}

【100,110,120,150】 总和= 480

示例:计算流元素

有一个count()方法可以用来知道流中元素的数量。请看下面的例子。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        System.out.println(numbers);
        Stream<Integer> stream = numbers.stream();
        long count = stream.count(); 
        System.out.println("Total Values = "+count);

    }
}

【100,110,120,150】 总值= 4

示例:列表到集合转换

有时我们需要将流从一种类型转换成另一种类型,然后我们在 Collectors 类中有预定义的方法。例如,要将列表转换为集合,我们可以使用toSet()方法。

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        numbers.add(110);
        System.out.println(numbers);
        Stream<Integer> stream = numbers.stream();
        Set<Integer> set = stream.collect(Collectors.toSet());
        System.out.println("Set Values = "+set);

    }
}

【100,110,120,150,110】 设定值=【100,150,120,110】

示例:列表到数组的转换

这是从一种类型转换到另一种类型的另一个例子。这里,我们使用流的toArray()方法将列表转换为数组。它返回一个对象数组。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class STDemo {
    public static void main(String[] args){

        List<Integer> numbers = new ArrayList<Integer>();  
        numbers.add(100);
        numbers.add(110);
        numbers.add(120);
        numbers.add(150);
        numbers.add(110);
        System.out.println(numbers);
        Stream<Integer> stream = numbers.stream();
        Object[] intArray = stream.toArray();
        for(Object element:intArray) {
            System.out.print(element+" ");
        }
    }
}

【100、110、120、150、110】 100 110 120 150 110