JDK8函数编程及JDK9中响应式流

一、前言

Spring5是基于Reactor框架实现响应式流,其中Spring Boot WebFlux是完全依赖reactor-core来实现;直接上手Spring WebFlux,虽然能简单使用,但对其原理未做深入了解,难免会有不少迷惑,故建议从基础出发,按照如下步骤进行学习:
1、掌握JDK8的函数式编程及stream流;

2、学习JDK9的flux的响应式流设计原理及实现机制

3、上手spring Boot webflux(JDK8函数式编程及stream流 + JDK9响应式流 的结合)

二、JDK8中的函数式编程及stream流

jdk8中最大的特点之一就是支持函数式编程及stream流,下面就其中重点做下基本的简介和示例:

(一)lamda表达式

Lambda 表达式,也可称为闭包,本质上来说其允许把函数作为一个方法的参数。

public class LambdaDemo1 {
    public static void main(String[] args) {
    	// 非lambda表达式代码示例
        Runnable thread1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("普通线程");
            }
        };
        new Thread(target).start();

        // jdk8 lambda表达式代码示例
        //返回一个接口,可以使用强转的方式(不过我觉得应该没人这么用)
        Runnable thread2 = (Runnable)() -> System.out.println("ok");
        new Thread(thread2).start();
    }
}

通过上面示例,可看出lambda表单式的很大的一个特点就是把复杂的代码逻辑,变得更为简洁和紧凑。

另外,lambda表达式还有其他的如下写法:

interface InterfaceDemo1 {
    int doubleNum(int i);
    int addNum(int i1, int i2);
}

public class LambdaDemo1 {
    public static void main(String[] args) {
    	// 函数逻辑多行时,需要加大括号
        InterfaceDemo1 i1 = (int i) -> {
            System.out.println("----------");
            return i * 2;
        };
        
    	// 函数逻辑仅为一行时,可省去大括号和return
        InterfaceDemo1 i2 = (int i) -> i * 2;
        
        // 参数可省去类型
        InterfaceDemo1 i3 = (i) -> i * 2;
        
    	// 单个参数时,可以省去括号
    	InterfaceDemo1 i4 = i -> i * 2;
    	
        // 多个参数时,需要加括号
        InterfaceDemo1 i5 = (i1, i2) -> i1 + i2;
    }
}

(二)函数式接口

函数式接口:只有一个方法的interface接口,一般通过添加注解 @FunctionalInterface来标注(不添加注解也可以,但建议加上注解以供编译时检验,加上注解后如果有多个方法会报错)

默认接口: interface接口中使用default关键字标注的实现方法;该方法可以不被实现,也可以被重写,和类中的方法一样,可以在方法使用this调用接口中的方法。

@FunctionalInterface
interface InterfaceDemo2 {
	// jdk8之后建议接口设计尽量的小,一个接口只做一件事,也就是更加便于函数式接口的使用
    int doubleNum(int i);
    // 默认方法
    default int add(int x, int y) {
        return x + y;
    }
}

public class LambdaDemo2 {
    public static void main(String[] args) {
        InterfaceDemo2 i1 = i -> i * 2;
        // 调用接口默认方法
        System.out.println(i1.add(3, 7));
        System.out.println(i1.doubleNum(20));
    }
}

(三)内置函数接口

1、四大核心函数式接口

函数式接口 参数类型 返回类型 方法 说明
Consumer T void void accept(T t) 无返回值,对指定T类型参数进行处理
Supplier T T get() 无入参,通过处理返回指定T类型对象
Function<T,R> T R R apply(T) 对指定T类型参数进行处理,通过处理返回指定R类型对象
Predicate T boolean boolean test(T) 对指定T类型参数进行处理,判断是否满足某种条件
public class FunctionDemo1 {
    public static void main(String[] args) {
     	// Consumer<T>
        Consumer<String> consumer = s -> System.out.println(s);
        consumer.accept("1");
        
        // Supplier<T>
        Supplier<String> supplier = () -> "2";
        System.out.println(supplier.get());
        
        // Function<T,R>
        Function<Integer, Integer> function = i -> i * 2;
        System.out.println(function.apply(3));
        
        // Predicate<T>
        Predicate<Integer> predicate = i -> i > 0;
        System.out.println(predicate.test(-4));
    }
}
2、 其他演变函数式接口
函数式接口 参数类型 返回类型 方法 说明
BiFunction<T,U,R> T,U R R apply(T t, U u) 对指定T类型和U类型参数进行处理,通过处理返回指定R类型对象
UnaryOperator T T T apply(T t) 对指定T类型参数进行处理,通过处理返回相同T类型对象,
其是Function<T,R>子接口
BinaryOperator T,T T T apply(T t, T t) 对两个指定的T类型参数进行处理,通过处理返回相同T类型对象,
其是BiFunction<T,U,R>子接口
BiConsumer<T,U> T,U void void accept(T t,U u) 无返回值,对指定T类型和U类型参数进行处理

(四)stream流

Stream流是一个来自数据源的元素队列并支持聚合操作,其有如下三个要素:

  1. 元素:特定类型的对象,基于该类型对象形成一个队列,且Stream流并
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值