JSR 335 之 Java里面的functional interface

1.函数式编程

在介绍functional interface前,先简单说明一下函数式编程

函数式编程的定义如下:“函数式编程是一种编程范式。它把计算当成是数学函数的求值,从而避免改变状态和使用可变数据。它是一种声明式的编程范式,通过表达式和声明而不是语句来编程

对函数式编程支持程度高低的一个重要特征是函数是否作为编程语言的一等公民出现,也就是编程语言是否有内置的结构来表示函数。作为面向对象的编程语言,Java 中使用接口来表示函数

functional interface 是在JDK 8里面引入的,定义在
jls-9.8 里面,一种特殊的接口

2.functional interface

先看一下interface的一些特点:

  • 所有在inferface里面定义的变量,必须初始化,默认是public static final类型的
  • 所有interface里面定义的方法,默认是public,
  • interface里面可以有default方法和static方法包含代码块,即方法有实现;这2种之外的方法,默认是abstrace
  • 子接口继承父接口里面,不继承static方法,
  • 接口中的成员类型声明是隐式的public和static
2.1 functional interface特点

Java中的functional interface是仅包含一个抽象(未实现)方法的接口。 除了单个未实现的方法外,functional interface还可以包含具有实现的default方法和static方法。

functional interface口中可以额外定义多个抽象方法,但这些抽象方法签名必须和Object的public方法一样,因为接口中定义的方法都是public类型的

总结一下,一个functional interface可以包含

  • 唯一的抽象方法
  • 已经实现的static方法
  • 已经实现的default方法
  • Object类的public方法

一个简单的例子

@FunctionalInterface
public interface MyFunctionInterface {

    int print();

    default String getName() {
        return "chadm";
    }

    static boolean notNullAndEmpty(String name) {
        return name != null && !name.equals("");
    }

    public String toString();

    public boolean equals(Object var1);
}

一个Java functional interface 可以通过一个Java Lambda表达式来实现

一个Java Lambda表达式实现了一个Java interface的单个方法,interface只能包包含有一个未实现的方法,换句话说,就是这个接口是一个Java functional interface

2.2 functional interface的简单使用

java.util.function中定义了几组类型的函数式接口以及针对基本数据类型的子接口。

  • Predicate 传入一个参数,返回一个bool结果, 方法为boolean test(T t)
  • Consumer 传入一个参数,无返回值,纯消费。 方法为void accept(T t)
  • Function<T,R> 传入一个参数,返回一个结果,方法为R apply(T t)
  • Supplier 无参数传入,返回一个结果,方法为T get()
  • UnaryOperator 一元操作符, 继承Function<T,T>,传入参数的类型和返回类型相同。
  • BinaryOperator 二元操作符, 传入的两个参数的类型和返回类型相同, 继承BiFunction<T,T,T>

简单用法

Function<Integer,Integer> addOne = (value) -> value+1;
System.out.println(addOne.apply(8));
        
Predicate predicate = (value) -> value != null;
System.out.println(predicate.test(null));

Supplier<Integer> supplier = () -> new Integer((int) (Math.random() * 1000D));
System.out.println(supplier.get());

Consumer<Integer> consumer = (value) -> System.out.println(value);
consumer.accept(101);

UnaryOperator<Person> unaryOperator =
                (person) -> { person.name = "chadm"; return person; };
Person me = new Person();
System.out.println(unaryOperator.apply(me));

BinaryOperator<Integer> binaryOperator = (x1, x2) -> x1 + x2;
System.out.println(binaryOperator.apply(100,1));

详细代码可以参考functioninterface

上面定义的都是单个操作,复合操作有

  • Predicate Composition 用and()和or()方法
  • Function composition 使用compose()和andThen

在需要functional interface的任何地方,我们都有三种选择

In addition to the usual process of creating an interface instance by declaring and instantiating a class (§15.9), instances of functional interfaces can be created with method reference expressions and lambda expressions (§15.13, §15.27).

  • 通过一个匿名内部类
  • 传递lambda表达式
  • 在某些情况下,传递方法引用(如System.out::println)而不是lambda表达式。

方法引用有如下几个:

ExpressionName :: [TypeArguments] Identifier
ReferenceType :: [TypeArguments] Identifier
Primary :: [TypeArguments] Identifier
super :: [TypeArguments] Identifier
TypeName . super :: [TypeArguments] Identifier
ClassType :: [TypeArguments] new
ArrayType :: new

注释类型**@FunctionalInterface**用于表示接口应作为functional interface(§9.8),它有助于及早发现不正确的方法声明。

可以使用不带@FunctionalInterface注解的lambda,就像可以不使用@Override注解来复写方法一样

参考:

  • https://stackoverflow.com/questions/36881826/what-are-functional-interfaces-used-for-in-java-8
  • http://tutorials.jenkov.com/java-functional-programming/functional-interfaces.html
  • https://developer.ibm.com/zh/languages/java/articles/j-lo-java8streamapi/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值