Java 8 引入了新的概念"函数式接口",用来支持Lambda表达式。函数式接口是指只有一个抽象方法的接口,即SAM接口(Single Abstract Method Interface)。在函数式接口中,可以定义多个默认方法和静态方法,但只能有一个抽象方法。
一、定义函数式接口
函数式接口的定义非常简单,只需要在接口上加上@FunctionalInterface注解即可,如下所示:
@FunctionalInterface public interface MyFunctionalInterface { void apply(String str); }
在这个接口中,我们定义了一个抽象方法apply(),接受一个字符串参数。注意到这里使用了@FunctionalInterface注解,这是为了方便编译器检查这个接口是否只包含一个抽象方法。
二、使用函数式接口
使用函数式接口可以通过Lambda表达式、方法引用等方式来提供实现。需要注意的是,提供的实现方法的参数和返回值必须与抽象方法一致。
1. Lambda表达式
Lambda表达式可以用来快速实现函数式接口,例如:
MyFunctionalInterface myLambda = (str) -> System.out.println(str); myLambda.apply("Hello Lambda!");
在这个例子中,我们定义了一个Lambda表达式,并创建了一个函数式接口实例,再调用apply()方法,输出"Hello Lambda!"。
2. 方法引用
另外一种实现函数式接口的方式是使用方法引用,例如:
MyFunctionalInterface myMethodRef = System.out::println; myMethodRef.apply("Hello Method Reference!");
这个例子使用了System类的静态方法println(),并将它作为方法引用传递给MyFunctionalInterface接口的实例。
三、函数式接口的分类
Java 8为我们提供了众多的函数式接口,这些接口被分为四类:函数型接口、供给型接口、消费型接口和断言型接口,下面我们来分别介绍。
1. 函数型接口
函数型接口(Function),它接受一个参数并且返回一个结果。如下所示:
@FunctionalInterface interface Function{ R apply(T t); }
其中T表示输入类型,R表示输出类型。例如:
Functionfunc = (x) -> x.toString(); System.out.println(func.apply(10));
这个例子定义了一个函数式接口func,接受一个整型参数并返回一个字符串类型的结果。在Lambda表达式中,我们将整型参数转换为字符串类型返回。
2. 供给型接口
供给型接口(Supplier),它不接受参数,但返回一个结果。如下所示:
@FunctionalInterface interface Supplier例如:{ T get(); }
Suppliersupplier = () -> "Hello World!"; System.out.println(supplier.get());
这个例子定义了一个供给型接口supplier,它返回一个固定的字符串"Hello World!"。
3. 消费型接口
消费型接口(Consumer),它接受一个参数但没有返回值。如下所示:
@FunctionalInterface interface Consumer{ void accept(T t); }
例如:
Consumerconsumer = (str) -> System.out.println(str); consumer.accept("Hello Consumer!");
这个例子定义了一个消费型接口consumer,接受一个字符串参数并将其打印到控制台上。
4. 断言型接口
断言型接口(Predicate),它接受一个参数并返回一个布尔类型的值。如下所示:
@FunctionalInterface interface Predicate例如:{ boolean test(T t); }
Predicatepredicate = (x) -> x > 0; System.out.println(predicate.test(-2)); System.out.println(predicate.test(2));
这个例子定义了一个断言型接口predicate,接受一个整型参数并返回一个布尔类型的值,表示这个整数是否大于0。我们在Lambda表达式中,对输入参数进行判断,返回true或false。
四、总结
本文详细介绍了函数式接口的定义、使用方法和分类,同时也给出了相应的代码示例。函数式接口是支持Lambda表达式的基础,掌握函数式接口对于掌握Java 8的Lambda表达式来说至关重要。