Java - Stream API 和 Optional 类的介绍

本文详细介绍了Java 8中的Stream API,包括为何使用Stream、Stream的创建方式、中间操作和终止操作,以及Optional类的使用方法。Stream API提供了高效处理数据的新方式,支持并行操作,有助于编写简洁的代码。Optional类则为解决Java中的空指针问题提供了容器解决方案,提供多种方法避免空值检测。
摘要由CSDN通过智能技术生成

Java 8中的新特性Stream API 优点:
1. 便于并行
2. 并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。 相比于串行的流,并行的流可以很大程度上提高程序的执行效率。
3. Java 8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地 通过parallel()与sequential()在并行流与顺序流之间进行切换。

1.强大的Stream API

  • Java8 中有两个最为重要的改变。第一个是Lambda表达式;另外一个则是Stream API

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

  • Stream 是Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、
    过滤和映射数据等操作。使用Stream API来并行执行操作,就类似于使用API使用SQL执行的数据库查询。
    也可以使用Stream API来并行执行操作。简言之,Stream API提供了一种高效且易于使用的处理数据的方式。

1.1. 为什么要使用Stream API ?

  • 实际开发中,项目中多数数据源都来自Mysql、Qracle等。但现在数据源可以更多了,有MongDB, Radis等,而这些
    NoSQL的数据就需要Java层面去处理。

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

1.2. 什么是Stream

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

  • “集合讲的是数据,Stream讲的是计算”

1.3. 注意:

  • Stream自己不会存储元素。
  • Stream不会改变源对象。相反,他们会返回一个持有结果的新的Stream
  • Stream操作时延迟执行的。这意味着他们会等到需要结果的时候才执行。

2. 操作 Stream 的三个步骤

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVBpBnBG-1649750340510)(README.assert/img_1.png)]

2.1 创建Stream的四种方式

1. 创建Stream方式一:通过集合

Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:

  • default Stream<E> stream() : 返回一个顺序流
  • defalut Stream<E> parallelStream() : 返回一个并行流
  • 代码测试:
      // 创建Stream方式一:通过集合
      @Test
      public void test01(){
         
          List<Employee> employees = EmployeeData.getEmployees();
    
          // default Stream<E> stream() : 返回一个顺序流
          Stream<Employee> stream = employees.stream();
          Object[] employeeps = stream.toArray(); // 将stream流转换为Object数组
    
          long t1 = System.currentTimeMillis();
          for (Object o : employeeps) {
         
              System.out.println(o);
          }
          long t2 = System.currentTimeMillis();
          System.out.println(t2 - t1); // 17 ms
          System.out.println("**************************\n");
    
          // default Stream<E> parallelStream() : 返回一个并行流
          Stream<Employee> employeeStream = employees.parallelStream();
          Object[] objects = employeeStream.toArray();
          t1 = System.currentTimeMillis();
          for (Object o : objects) {
         
              System.out.println(o);
          }
          System.out.println(System.currentTimeMillis() - t1); // 0 ms
      }
    

2. 创建Stream方式二:通过数组

Java8中的Arrays的静态方法 stream() 可以获取数组流

  • static <T> Stream<T> stream(T[] array) : 返回一个流

重载形式,能够处理对应基本类型的数组:

  • public static IntStream stream(int[] array)
  • public static LongStream stream(long[] array)
  • public static DoubleStream stream(double[] array)
  • 代码测试:
      // 创建Stream方式二:通过数组
      @Test
      public void test02() {
         
          // 调用Arrays类的 static <T> stream<T> stream(int[] array):返回一个流
    
          int[] arr = new int[] {
         1,2,3,4,5,6};
          IntStream stream = Arrays.stream(arr);
          System.out.println(stream.sum()); // 21
    
          Employee e1 = new Employee(1, "jack");
          Employee e2 = new Employee(2, "lisi");
          Employee[] arr2 = new Employee[]{
         e1, e2};
          Stream<Employee> stream2 = Arrays.stream(arr2);
          System.out.println(stream2.toString());
      }
    

3. 创建Stream方式三:通过Stream的of()

  • 可以调用Stream类静态方法of(), 通过显式值创建一个流。它可以接收任意数量的参数。
  • public static<T> Stream<T> of(T... values) : 返回一个流
  • 代码测试:
      // 创建Stream方式三:通过Stream的of()
      @Test
      public void test03() {
         
          Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
      }
    

4. 创建Stream方式四:创建无限流

可以使用静态方法 Stream.iterate() 和 Stream.generate()创建无限流

  • 迭代:public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
  • 生成:public static<T> Stream<T> generate(Supplier<T> s)
  • 代码测试:
      // 创建Stream方式四:创建无限流
      public void test04() {
         
          // 1. 迭代Stream.iterate(),遍历前10个偶数
          Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
    
          // 2. 使用生产函数来产生10个随机数
          Stream.generate(Math::random).limit(10).forEach(System.out::println);
      }
    

2.2 Stream的中间操作

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

1. 筛选与切片

方法 描述
filter(Predicate p) 接口Lambda,从流中排出某些元素
distinct() 筛选,通过流所生成元素的hashCode()和equals()去除重复元素
limit(long maxSize) 截断流,使其元素不超过给定数量
skip(long n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
  • 代码测试:
package StreamAPITest;

import MethodReferenceTest.Employee;
import MethodReferenceTest.EmployeeData;
import org.junit.Test;

import java.util.List;
import java.util.stream.Stream;

/**
* @ClassName: StreamAPITest2
* @Description: Java - Stream API的中间操作
* @author: zhilx
* @version: v1.0
* @data: 2022/4/12 9:15
* @node: 测试Stream的中间操作:
*
*/
public class StreamAPITest2 {
   

    // 1. 筛选与切片
    @Test
    public void test01() {
   
        List<Employee> list = EmployeeData.getEmployees();
        System.out.println("list中元素的数量:" + list.size());
        /**
         * note:对流进行终止操作后,该流就被关闭,相等于Iterator的调用,关闭后必须创新创建或打开才可以继续使用。
         */

        // filter(Predicate p) : 接口Lambda,从流中排出某些元素
        // 练习:查询员工表中年龄小于45的员工信息
        System.out.println("-----打印表中年龄大于45的CEO的数量-----");
        Stream<Employee> stream = list.stream();
        stream.filter(e -> e.getAge() > 45).forEach(System.out::println);

        // note: forEach()表示Stream的终止操作,当调用该条件时已经将Stream关闭,因此后面的流无法指向相应的操作
        //       如果想要执行,则必须重新创建Stream流
        System.out.println("\n-----截断表中的前5个元素-----");
        // limit(long maxSize) : 截断流,使其元素不超过给定数量
        list.stream().limit(5).forEach(System.out::println);

        System.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值