函数式接口
什么是函数式接口?
只有一个抽象方法的接口
public interface MyInterface {
void myMethod();
}
注意,函数式接口可以有其他方法,但是抽象方法只能有一个。当在一个接口中有很多方法的时候可以用 @FunctionalInterface注解来判断此接口是否为函数式接口。如果接口中没有或存在2个及以上的抽象方法,添加注解会编译报错。
//错误示范
@FunctionalInterface
public interface MyInterface {
void myMethod1();
void myMethod2();
}
函数式接口的使用
一般来说是作为一个方法的参数来传递
public class Demo {
public static void main(String[] args) {
doSomething(() -> System.out.println("aaa"));
}
private static void doSomething(MyInterface inter) {
inter.myMethod();
}
}
@FunctionalInterface
public interface MyInterface {
public abstract void method();
}
public class MyInterfaceImpl implements MyInterface{
@Override
public void method() {
}
}
函数式接口的好处
利用Lambda的延迟性可以避免性能浪费
例一
public class Demo{
public static void main(String[] args) {
String msgA = "aaa";
String msgB = "bbb";
String msgC = "ccc";
testMethod(1, msgA + msgB + msgC);
}
private static void testMethod(int level, String msg) {
if (level == 1) {
System.out.println(msg);
}
}
}
例二
public class Demo{
public static void main(String[] args) {
String msgA = "aaa";
String msgB = "bbb";
String msgC = "ccc";
testMethod(1, () -> msgA + msgB + msgC);
}
private static void testMethod(int level, MyInterface inter) {
if (level == 1) {
System.out.println(inter.method());
}
}
}
分析:例一中先是对msgA,msgB,msgC进行拼接,然后在传递,也就是说 level 不管是不是1,都会有拼接这个步骤,即使最后不满足条件不能输出;例二中是最后满足条件才有拼接这个步骤,如果不满足是不会有拼接这个步骤,这样就避免了性能浪费。
常用函数式接口
Supplier接口
仅包含一个无参的方法:T get()。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
public class Demo {
public static void main(String[] args) {
String msgA = "aaa";
String msgB = "bbb";
System.out.println(getString(() -> msgA + msgB));
}
private static String getString(Supplier<String> function) {
return function.get();
}
}
Consumer接口
与Supplier接口相反,它不是生产一个数据,而是消费一个数据
public class Demo {
public static void main(String[] args) {
consumeString(s -> System.out.println(s));
}
private static void consumeString(Consumer<String> function) {
function.accept("aaa");
}
}