目录:
1.函数式接口的基本概念和格式
2.函数式编程
3.函数式接口作为方法的参数和方法的返回值
4.常用函数式接口
1.函数式接口的基本概念和格式
1.函数式接口的基本概念:
函数式接口在Java中是指:
有且仅有一个抽象方法的接口。
函数式接口,即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda,所以函数式接口就是可 以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。
如果对Lambda表达式不是很清除那么可以参照这一篇博客:Lambda表达式详解
介绍一个语法糖概念:
语法糖:是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实 底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,Java中的Lambda可以被当做是匿名内部 类的“语法糖”,但是二者在原理上是不同的。
2.格式:
只要满足有一个抽象方法的接口即可,当然也可以包含其他的方法(默认静态私有等等)
修饰符 interface 接口名称
{
(public abstract) 返回值类型 方法名称(可选参数信息);
// 其他非抽象方法内容
}
由于接口中默认类型为public abstract 所以带不带都行
3.@FunctionalInterface注解:
Java 8中专门为函数式接口引入了一个新的注解:
@FunctionalInterface
。该注 解可用于一个接口的定义上
@FunctionalInterface
public interface MyFunctionalInterface
{
void myMethod(); }
我们这一个注解当我们在定义函数式接口的时候发送了错误,那么注解的编译就不通过:
当我们去掉一个抽象的方法的时候就,注意就会正常通过编译:
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注 意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
2.函数式编程
1.Lambda表达式的延迟执行
看一段代码:
public class Demo01Logger {
private static void log(int level, String msg) {
if (level == 1)
{
System.out.println(msg);
}
}
public static void main(String[] args)
{
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
log(1, msgA + msgB + msgC);
}
}
分析一下这段代码,发现存在浪费,首先log方法传进两个参数,第一个参数是一个数字,第二个参数是一个拼接后的字符串,那么正常调用的时候我们就要先把字符串拼接好后再调用log函数,如果第一个参数不是1,那么拼接字符串就显得没用,白拼接了,这样就造成了浪费,这时候就可以使用Lambda解决
想要解决问题,那么首先我们了解Lambda的使用特点和前提:
1.使用特点:
延迟加载
2.使用前提:必须存在函数式接口
具体解决的代码实现:
package untl1;
public class Demo02LoggerLambda
{
private static void log(int level, MessageBuilder builder)
{
if (level == 1)
{
System.out.println(builder.buildMessage());
}
}
public static void main(String[] args)
{
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
log(1, ()-> msgA+msgB+msgC);
}
}
@FunctionalInterface
interface MessageBuilder {
String buildMessage();
}
此段代码就完美的解决上述问题,那么,我们如何证实在第一个参数不是1的时候不进行字符串的拼接呢,我们可以在第二个参数加一个书输出语句即
package untl1;
public class Demo02LoggerLambda
{
private static void log(int level, MessageBuilder builder)
{
if (level == 1)
{
System.out.