Java 8 中有两大最为重要的改变。第一个是 Lambda 表达式;另一个就是 Stream API

Stream API(java . util . stream)把真正的函数式编程风格引入到 Java 中。这是目前为止对 Java 类库最好的补充,因为 Stream API 可以极大的提供 Java 程序员的生产力,让程序员写出更高效、干净、简洁的代码

说白了,Stream 就是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列

目录

Stream与Collection集合的区别

使用Stream的注意事项

Stream操作的三个步骤

Stream的实例化

Stream的中间操作

Stream的终止操作


Stream与Collection集合的区别

Collection 是一种静态的内存数据结构,而 Stream 是有关计算的。前者是主要面向内存,存储在内存中,后者主要是面向 CPU,通过 CPU 实现计算

使用Stream的注意事项

1. Stream 自己不会存储元素

2. Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream

3. Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

Stream操作的三个步骤

1. 创建 Stream

一个数据源(集合、数组等),获取一个流

2. 中间操作

一个中间操作链,对数据源的数据进行处理

3. 终止操作

一旦执行终止操作,就执行中间操作链,并产生结果。之后,就不会被再使用

Stream的实例化

import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class StreamTest {
    //方式一:通过集合创建
    @Test
    public void test() {
        List list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(7);
        list.add(9);
        //default Stream stream():返回一个顺序流
        Stream stream = list.stream();
        //default Stream parallelStream():返回一个并行流
        Stream parallelStream = list.parallelStream();
    }
    //方式二:通过数组
    @Test
    public void test2(){
        int[] arr = new int[]{1,2,3,5,6,8};
        //调用 Arrays 类的 static Stream stream(T[] array): 返回一个流
        IntStream stream = Arrays.stream(arr);
    }
    //方式三:通过 Stream 的 of()
    @Test
    public void test3(){
        Stream<Integer> stream = Stream.of(1,3,4,5,7,8);
    }
    //方式四:创建无限流
    @Test
    public void test4(){
        //迭代
        //public static Stream iterate(final T seed,final UnaryOperator<T> f)
        Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println);
        //生成
        //public static Stream generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }
}

Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理。而在终止操作时一次性全部处理,称为 “惰性求值”

filter(Predicate)将结果为false的元素过滤掉
map(fun)转换元素的值,可以用方法引元或者lambda表达式
flatMap(fun)若元素是流,将流摊平为正常元素,再进行元素转换
imit(n)保留前n个元素
skip(n)跳过前n个元素
distinct()剔除重复元素
sorted()将Comparable元素的流排序
sorted(Comparator)将流元素按Comparator排序
peek(fun)流不变,但会把每个元素传入fun执行,可以用作调试
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamTest {
    @Test
    public void test() {
        List list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(9);
        list.add(7);
        //default Stream stream():返回一个顺序流
        Stream stream = list.stream();
        //查询大于5的值
        stream.filter(l -> l.hashCode() > 5).forEach(System.out::print);
        System.out.println();
        //截断流,使其元素不超过指定数量
        list.stream().limit(3).forEach(System.out::print);
        System.out.println();
        //跳过元素,返回一个扔掉了前n个元素的流
        list.stream().skip(3).forEach(System.out::print);
        System.out.println();
        //筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
        list.add(1);
        list.stream().distinct().forEach(System.out::print);
        System.out.println();
        //map(Function f)接受一个函数作为参数,将元素转换成其他形式或提取信息
        List<String> list1 = Arrays.asList("aa","bb","cc");
        list1.stream().map(str -> str.toUpperCase()).forEach(System.out::print);
        System.out.println();
        //排序:sorted()自然排序
        list.stream().sorted().forEach(System.out::print);
    }
}

>>> 97
    149
    7
    1497
    AABBCC
    11479

Stream的终止操作

终止操作会从流的流水线生成结果。其结果可以是任何不是流的值

流进行了终止操作后,不能再次使用

max(Comparator)

min(Comparator)

count()

findFirst()返回第一个元素
findAny()返回任意元素
anyMatch(Predicate)任意元素匹配时返回true
allMatch(Predicate)所有元素匹配时返回true
oneMatch(Predicate)没有元素匹配时返回true
reduce(fun)从流中计算某个值,接受一个二元函数作为累积器,从前两个元素开始持续应用它,累积器的中间结果作为第一个参数,流元素作为第二个参数
reduce(a, fun)a为幺元值,作为累积器的起点
reduce(a, fun1, fun2)与二元变形类似,并发操作中,当累积器的第一个参数与第二个参数都为流元素类型时,可以对各个中间结果也应用累积器进行合并,但是当累积器的第一个参数不是流元素类型而是类型T的时候,各个中间结果也为类型T,需要fun2来将各个中间结果进行合并

iterator()

forEach(fun)

forEachOrdered(fun)可以应用在并行流上以保持元素顺序

toArray()

toArray(T[ ] :: new)返回正确的元素类型

collect(Collector)

collect(fun1, fun2, fun3)fun1转换流元素;fun2为累积器,将fun1的转换结果累积起来;fun3为组合器,将并行处理过程中累积器的各个结果组合起来

Collectors: 

import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class StreamTest {
    @Test
    public void test() {
        List<Integer> list = new ArrayList();
        list.add(1);
        list.add(4);
        list.add(9);
        list.add(7);
        //是否所有数都大于5
        boolean allMatch = list.stream().allMatch(l -> l.hashCode() > 5);
        System.out.println(allMatch);
        //是否存在大于5的事
        boolean anyMatch = list.stream().anyMatch(l -> l.hashCode() > 5);
        System.out.println(anyMatch);
        //检查是否没有匹配的元素
        boolean noneMatch = list.stream().noneMatch(l -> l.hashCode() > 5);
        System.out.println(noneMatch);
        //返回第一个元素
        Optional l = list.stream().findFirst();
        System.out.println(l);
        //返回最小的数
        Optional l1 = list.stream().max((l4,l3) -> Double.compare(l4.hashCode(),l3.hashCode()));
        System.out.println(l1);
        //内部迭代
        list.stream().forEach(System.out::print);
        System.out.println();
        //reduce()可以将流中的元素反复结合起来,得到一个值
        //计算总和
        Integer sum1 = list.stream().reduce(0, Integer::sum);
        System.out.println(sum1);
        //查找大于5的值,返回一个 List 或 Set
        List<Integer> collect = list.stream().filter(l6 -> l6 > 5).collect(Collectors.toList());
        System.out.print(collect);
    }
}

>>> false
    true
    false
    Optional[1]
    Optional[9]
    1497
    21
    [9, 7]
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐