java 函数接口_Java四大函数式接口

四大函数式接口指的是Consumer、Function、Predicate、Supplier

0add5a782ebe6134b2056b94745d8e37.png

函数式编程

lamabda表达式

函数式接口:在java中是指:有且仅有一个抽象方法的接口。也即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。

lambda表达式表示函数式接口的实例。

lambda表达式的类型是一个函数式接口类型。

备注:“语法糖"是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部类的“语法糖”,但是二者在原理上是不同的。

以下是这种函数式接口的示例:

@FunctionalInterfaceinterfaceProcessor {intgetStringLength(String str);

}

我们可以为其函数式接口实例赋值lambda表达式。

Processor stringProcessor = (String str) -> str.length();

函数式接口格式:接口中只能存在一个抽象方法

修饰符 interface接口名称{public abstract返回值 方法名称(参数列表)//其他方式

}//public abstract 可以不写 编译器自动加上

修饰符 interface接口名称{

返回值 方法名称(参数列表)//其他方式

}

方法前面的public abstract 可以不写,编译器会自动加上

@FunctionalInterface注解

@FunctionalInterface //标明为函数式接口

public abstractMyFunctionInterface{void method(); //抽象方法

}

一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。(该接口是一个标记接口)

Javadoc关于函数式接口的规范

An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface’s abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.

Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.

If a type is annotated with this annotation type, compilers are required to generate an error message unless:

• The type is an interface type and not an annotation type, enum, or class.

• The annotated type satisfies the requirements of a functional interface.

However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a Functional Interface annotation is present on the interface declaration.

根据Java语言规范的定义,一个使用了该注释的接口类型声明将被视为一个函数式接口。从概念上讲,一个函数式接口有且只有一个抽象方法。由于默认方法(default)已经有了实现,所以它们不是抽象方法。

如果一个接口中声明的抽象方法是重写了超类Object类中任意一个public方法,那么这些抽象方法并不会算入接口的抽象方法数量中。

因为任何接口的实现都会从其父类Object或其它地方获得这些方法的实现。

注意:函数式接口的实现可以由Lambda表达式、方法引用、构造器引用等方式实现。

如果一个类型使用了该注释@FunctionalInterface,除非这个类型是一个接口类型(而不是一个注释类型、枚举或类),否则编译器将会生成一个错误信息。同时使用该注释的接口满足函数式接口的要求,即一个函数式接口有且只有一个抽象方法。

但是编译器会将所有定义为函数式接口(满足函数式接口要求)的接口视为函数式接口,而不管这个接口声明中是否使用了函数式接口的注释(即@FunctionalInterface)。

从中我们可以知道:

一个函数式接口有且只有一个抽象方法。

默认方法不是抽象方法,因为它们已经实现了。

重写了超类Object类中任意一个public方法的方法并不算接口中的抽象方法。

比如Comparator接口,这是jdk当中的一个函数式接口:

ae309a42b2e24c25269f09b4c1a29214.png

Comparator的接口方法(含有大量的default方法):

含有两个抽象方法(虽然没有被显示声明为abstract):

compare(T o1,T o2),equals(Object obj)

c403288ad1338d35004294dfbd824e30.png

Java8中的函数式接口定义是只有一个抽象方法的接口,但是这个Comparator中,好像是有多个抽象方法,为什么它也叫函数式接口呢?。

但是实际上只有一个:int compare(T o1,T o2)

defualt方法  默认方法有点类似静态方法。

equals方法是Object的方法。所以虽然Comparator接口中有两个抽象方法compare和equals,但equals并不算入接口中的抽象方法,所以Comparator接口还是满足函数式接口的要求,Comparator接口是一个函数式接口。

使用Lambda进行传参

假设有一个 方法使用该函数式接口作为参数,那么就可以使用Lambda进行传参.如线程中的Runable接口

public classTest_Functional {//定义一个含有函数式接口的方法

public static voiddoSomthing(MyFunctionalInterface functionalInterface) {

functionalInterface.method();//调用自定义函数式接口的方法

}public static voidmain(String[] args) {//调用函数式接口的方法

doSomthing(()->System.out.println("excuter lambda!"));

}

}

@FunctionalInterface//标明为函数式接口

public abstractMyFunctionInterface{void method(); //抽象方法

}

使用Lambda作为返回值

如果一个方法的返回值类型是一个函数式接口,那么就可以直接返回一个Lambda表达式

public classlambda_Comparator {//下面给出 lambda 以及实际替代的内部类写法

private static ComparatornewComparator(){return (a,b)->b.length()-a.length();

}private static ComparatornewComparator1(){return new Comparator() {

@Overridepublic intcompare(String a, String b) {return b.length()-a.length();

}

};

}public static voidmain(String[] args) {

String[] array={"abc","ab","abcd"};

System.out.println(Arrays.toString(array));

Arrays.sort(array, newComparator1());//方式一

Arrays.sort(array,(a,b)->b.length()-a.length());//更简单的方式

System.out.println(Arrays.toString(array));

}

}

Arrays.sort(...)其中的一种参数形式如下:

sort(T[] a, Comparator super T> c)//根据指定的比较器引发的顺序对指定的对象数组进行排序。

常用函数式接口

...未完

原文:https://www.cnblogs.com/yanl55555/p/13550132.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值