java对函数式编程的支持

java对函数式的支持

java8提供了lambda表达式、方法引用、预定义函数接口来适配函数式编程。

java将lambda表达式看做函数式接口的对象实例,但这在设计层面上就已经满足一等值的概念了。

函数式接口

jdk已经提供了一系列的函数式接口(Package java.util.function)了,例如Consumer、Supplier、Function、Predicate以及其他的出于拆箱装箱性能损耗的DoubleConsumer、IntPredicate,和基于多参数的BiConsumer等。

如果function包下的接口还不能满足你的需求,可以配合桑除虫@FunctionalInterface声明自己的函数式接口。对于函数式接口而言,@FunctionalInterface其实是可加可不加的,它的作用是在编译时看看你的函数式接口是否只有一个实例方法。

因为在java中,是通过实例化函数式接口的方式(常基于lambda表达式)来进行函数式支持的。

// 自定义消费int的函数式接口
@FunctionalInterface
interface consumeInt {
    
    
    void consume(int i);
}
// 实例化函数式接口
consumeInt consumeInt = i -> System.out.println(i);

lambda表达式

lambda表达式的语法很简单:

(parameters) -> expression // 若只有一条执行语句的话不带{}(parameters) ->{
    
     statements; } // 多条执行语句带{},且带;

lambda表达式会自动推断参数的类型。一般来说是依赖于函数式接口指定的参数类型,但配合java范型的使用使lambda表达式拥有更为丰富的表达能力:

Function<String, String> function = str -> // 使用范型指定传入String 传出String
    new StringBuilder(str).append("-").append(str.length()).toString();
// 当然也可以手动指定类型
Function<String, String> function = (String str)->...

方法引用

参考文章

方法引用可以分为四类: 指向静态方法的、指向lambda表达式中变量的实例方法的、指向外部对象的实例方法的、构造函数的。

在java中方法的声明包括6个方面:修饰符、返回值、方法名、方法参数、异常列表、方法体。使用方法引用时:

  1. 修饰符要复合条件(访问不到的方法自然方法引用也不可用)
  2. 确保方法签名的匹配( 方法签名包含返回值和方法参数)
  3. 确保异常列表的兼容。(要求被引用的方法比需要的方法异常列表更小)
public class FunctionRefSt {
    
    
  	// 静态方法
    public static int length(String str) {
    
    
        return str.length();
    }
		// 实例方法
    public int lengthIns(String str) {
    
    
        return str.length();
    }
		// 四种引用的展示
    @Test
    public void funcRef() {
    
    
        Optional<String> opt = Optional.of("hello world");
        /*以下三种输出都是11*/
        // 静态方法引用
        opt.map(FunctionRefSt::length).ifPresent(System.out::println);
        // 内部实例方法引用
        opt.map(String::length).ifPresent(System.out::println);
        // 外部实例方法引用
        FunctionRefSt functionRefSt = new FunctionRefSt();
        opt.map(functionRefSt::lengthIns).ifPresent(System.out::println);

        /*构造函数引用实例*/
        // 利用optional避免空指针
				System.out.println(Optional.<List>ofNullable(null).orElseGet(/*引用了构造方法*/ArrayList::new).size());
	      //输出0
    }
}

模式匹配

模式匹配可以简单的理解成增强switch表达式。java8目前还不支持模式匹配,其switch能支持的匹配类型还是比较少的: 枚举、String、byte、short、int、char以及一些基本类型的包装类。在java12之后,switch表达式进行了一番的优化,jdk13switch特性:

// jdk12
switch (type) {
    
    
    case "all" -> System.out.println("列出所有帖子");
    case "auditing" -> System.out.println("列出审核中的帖子");
    case "accepted" -> System.out.println("列出审核通过的帖子");
    case "rejected" -> System.out.println("列出审核不通过的帖子");
    default -> System.out.println("参数'type'错误,请检查");
}
// jdk13
String value = switch (i) {
    
    
    case  0 -> "zero"
    case  1 -> "one"
    case  2 -> "two"
    default -> "many"
};
System.out.println(value);

猜你喜欢

转载自blog.csdn.net/qq_38619183/article/details/112482404