java 8强大的 Stream API

Posted 馆主阿牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 8强大的 Stream API相关的知识,希望对你有一定的参考价值。

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:java 小白到高手的蜕变🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥

目录

前言

java 8中有两个最为重要的改变,第一个就是前面总结的Lambda表达式,另为一个则是Stream API。
这节我将总结一下!

Stream API 说明

  • Stream API ( java.util.stream )把真正的函数式编程风格引入到 Java 中。这
    是目前为止对 Java 类库最好的补充,因为 Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。
  • Stream 是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简言之, Stream API 提供了一种高效且易于使用的处理数据的方式。

为什么要使用Stream API

  • 实际开发中,项目中多数数据源都来自于 mysql , Oracle 等。但现在数
    据源可以更多了,有 MongDB , Redis 等,而这些 NoSQL 的数据就需要 Java 层面去处理。
  • Stream 和 Collection 集合的区别: Collection 是一种静态的内存数据
    结构,而 Stream 是有关计算的。前者是主要面向内存,存储在内存中,后者主要是面向 CPU ,通过 CPU 实现计算。

什么是 Stream

Stream 到底是什么呢?
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据, Stream 讲的是计算!”
注意:
① Stream 自己不会存储元素。
② Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream .
③ Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream 的操作三个步骤

1、创建 Stream
一个数据源(如:集合、数组),获取一个流
2、中间操作
一个中间操作链,对数据源的数据进行处理
3、终止操作(终端操作)
一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

创建 Stream 的四种方式(Stream的实例化)

public class Demo 
    public static void main(String[] args) 
        // 创建Stream的方式一:通过集合
        // default Stream<E> stream():返回一个顺序流
        List list = new ArrayList();
        Stream stream1 = list.stream();
        // default Stream<E> paralleStream():返回一个并行流
        Stream stream2 = list.parallelStream();

        // 创建Stream的方式二:通过数组
        int[] arr = new int[]1,2,3;
        // 调用Arrays类的static<T> Stream<T> stream(T[] array):返回一个流
        IntStream stream = Arrays.stream(arr);

        // 创建Stream的方式三:通过Stream的of()
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);

        // 创建Stream的方式四:创建无限流
        // 迭代
        // public static<T> Stream<T> iterate(final T seed,final UnaryOperator<T> f)
        // 例:遍历前10个偶数
        Consumer<Integer> println = System.out::println;
        Stream.iterate(0, t -> t+2).limit(10).forEach(println);
        
        // 生成
        // public static<T> Stream<T> generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    


Stream 的中间操作

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

筛选与切片

// Stream 的中间操作
  // 筛选与切片
  List<String> list = Arrays.asList("阿牛", "小牛", "大牛", "小红");
  Stream<String> stream = list.stream();
  // filter(Predicate p)  -- 接收Lambda,从流中排出某些信息
  stream.filter(str -> str.contains("牛")).forEach(System.out::println);   //forEach终止操作,传入一个函数式接口中的消费者

 List<String> list = Arrays.asList("阿牛", "小牛", "大牛", "小红");

 Stream<String> stream1 = list.stream();
 // limit(n)  -- 截断流,使其元素不超过给定数量
 stream1.limit(2).forEach(System.out::println);
 System.out.println("----------");

 Stream<String> stream2 = list.stream();
 // skip(n)  -- 跳过元素,返回一个人扔掉前n个元素的流,若流中元素不足n个,则返回一个空流
 stream2.skip(3).forEach(System.out::println);
 System.out.println("----------");

 List<String> list1 = Arrays.asList("阿牛", "小牛", "大牛", "小红","阿牛"); // 添加一个重复元素
 Stream<String> stream3 = list.stream();
 // distinct() -- 筛选,通过流所生成元素的hashcode()和equals()去除重复元素
 stream3.distinct().forEach(System.out::println);

映射

// 映射
// map(Function f) -- 接受一个函数作为参数,这个函数应用到每个元素上,将元素映射为一个新的元素
List<String> list = Arrays.asList("a", "b", "c", "d");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

// flatMap(Function f) -- 接受一个函数作为参数,将流中的每个值都映射为另一个流,然后把所有的流连在一起
// 这个我不举例子了,主要可以处理结集合的嵌套,两层嵌套直接用flatMap就不用写两层forEach了

排序

// 排序
// sorted()  --自然排序
List<Integer> list= Arrays.asList(12, 14, 3, 6, 10);
list.stream().sorted().forEach(System.out::println);
System.out.println("--------");
// sorted(Comparator com)  --定制排序
list.stream().sorted((s1,s2) -> -Integer.compare(s1,s2)).forEach(System.out::println);

Stream 的终止操作

匹配与查找



这里不再写案例!

归约

// 归约
// reduce(T identity,BinaryOperator) - 可以将流中的元素反复结合起来,得到一个值,返回T
// T identity是初始值,BinaryOperator是函数式接口,接受T类型的两个值,返回T类型。
// 例:求1-10的和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum); //55

// reduce(BinaryOperator) - 可以将流中的元素反复结合起来,得到一个值,返回optional<T>

收集


  // 收集
  // collect(Collector c)
  // 例:过滤列表中大于5的元素,结果返回一个List

  List<Integer> list = Arrays.asList(1, 2, 5, 6, 8, 7);
  List<Integer> list1 = list.stream().filter(integer -> integer > 5).collect(Collectors.toList());
  System.out.println(list1);

结语

还是比较抽象的,你们可以下去多了解了解!

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门

java8新特性-Stream(API)

1.处理流程

获取数据源 -> 数据转换 -> 获取结果

2.获取stream对象

(1)从集合或者数组中获取 Collection.stream(),如accounts.stream()

            Collection.prarallelStream() 获取并行Stream对象

            Arrays.stram(T t)

(2)BufferReader   BufferReader.lines() -> stream()

(3)静态工厂     java.util.stream.IntStream.range() -> stream()

           java.nio.file.Files.walk() -> stream

(4)自行构建     java.util.Spliterator -> stream

(5)更多       Random.ints() -> stream

           Pattern.splitAsStream() -> stream

3.中间操作方式

操作结果是一个Stream,中间操作可以有一个或多个的中间操作,需要注意的是,中间操作只记录操作方式,不做具体执行,直到结束操作发生时,才做数据的最终执行。

中间操作就是:就是业务逻辑处理。

中间操作过程:无状态:数据处理时,不受前置中间操作的影响(map/filter/peek/parallel/sequential/unordered)

       有状态:数据处理时,受前置中间操作的影响(distinct/sorted/limit/skip)

4.终结操作

需要注意的是,一个Stream对象,只允许一个终结操作,这个操作一旦发生,就会真实处理数据,并且不可逆。

终结操作:非短路操作:当前Stream对象必须处理完集合中的所有数据,才能得到处理结果(foreach/foreachOrdered/toArray/reduce/collect/min/max/count/iterator)

       短路操作:当前Stream对象在处理过程中,一旦满足某个条件,就可以得到返回结果(anyMatch/allMatch/noneMatch/findFirst/findAny等)(对一个无限大的stream)

以上是关于java 8强大的 Stream API的主要内容,如果未能解决你的问题,请参考以下文章

重学Java 8新特性 | 第7讲——强大的Stream API

Java_常用类

强大的 Stream 函数式编程

java基础之二十一-;Stream api

Java8 中的 Stream 那么强大,那你知道它的原理是什么吗?

精细篇Java8强大的stream API接口大全(代码优雅之道)