函数式接口:只包含一个抽象方法的接口。其可以包含多个默认方法、类方法,但抽象方法只能有一个。
因此一个函数式接口的实例可用匿名内部类形式来表示,而匿名内部类在jdk8中可被Lambda表达式代替。【Lambda表达式介绍参照我另一篇:https://blog.csdn.net/qq_26012495/article/details/116614342?spm=1001.2014.3001.5501】
Java8专门为函数式接口提供了@FunctionalInterface注解来校验该接口是否为函数式接口。
下面举例:
在Animal接口中,实现了jdk8新引入的默认方法及静态方法。并声明唯一的抽象方法eat,在类头标注@FunctionalInterface无报错,说明该接口为一个标准的函数式接口。
@FunctionalInterface
public interface Animal {
/**
* jdk8新引入:默认方法,解决新增接口方法变动全部实现类问题
*/
default void print() {
System.out.println("我是一个不知道什么类型的动物");
}
/**
* jdk8新支持:接口可写入静态方法
*/
static void staticFunction() {
System.out.println("我是一个静态方法");
}
/**
* 抽象方法
*/
public abstract void eat();
}
当在代码中使用匿名内部类实现eat方法:
Animal animal = new Animal() {
@Override
public void eat() {
System.out.println("吃");
}
};
使用Lambda表达式代替:
Animal animal = () -> System.out.println("吃");
jdk8之前已经存在的常见的函数式接口
- java.lang.Runnable
- java.util.concurrent.Callable
- java.util.Comparator
jdk8新引入的常见函数式接口
接口名称 | 入参类型 | 返回类型 | 唯一抽象方法 | 说明 |
---|---|---|---|---|
Consumer<T> 【消费型接口】 | T | void | void accept(T t); | 对类型为T的对象操作,并无返回 |
Supplier<T> 【供给型接口】 | 无 | T | T get(); | 没有入参,返回类型为T的对象 |
Function<T,R> 【函数型接口】 | T | R | R apply(T t); | 对类型为T的对象操作,返回类型为R的对象 |
Predicate<T> 【断言型接口】 | T | boolean | boolean test(T t); | 对类型为T的对象操作,确定其是否满足条件,返回布尔值 |
Consumer<T>
public static void main(String[] args) {
/**
* 1.7
*/
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println("这是jdk1.7的写法" + s);
}
};
test(consumer, "s");
/**
* 1.8
*/
test(s -> System.out.println("这是jdk1.8的写法" + s), "s");
}
/**
* 入参为Consumser<T>的方法
*
* @param consumer
* @param str
*/
public static void test(Consumer<String> consumer, String str) {
consumer.accept(str);
}
Supplier<T>
public static void main(String[] args) {
/**
* 1.7
*/
Supplier<String> supplier = new Supplier<String>() {
@Override
public String get() {
return "这是jdk1.7的写法";
}
};
test(supplier);
/**
* 1.8
*/
test(() -> "这是jdk1.8的写法");
}
/**
* 入参为Supplier<T>的方法
*
* @param supplier
* @return
*/
public static String test(Supplier<String> supplier) {
return supplier.get();
}
Function<T,R>
public static void main(String[] args) {
/**
* 1.7
*/
Function<Integer, String> function = new Function<Integer, String>() {
@Override
public String apply(Integer integer) {
return String.valueOf(integer);
}
};
test(function, 5);
/**
* 1.8
*/
test(integer -> String.valueOf(integer), 5);
}
/**
* 入参为Function<T,R>的方法
*
* @param function
* @param num
* @return
*/
public static String test(Function<Integer, String> function, Integer num) {
return function.apply(num);
}
Predicate<T>
public static void main(String[] args) {
/**
* 1.7
*/
Predicate<String> predicate = new Predicate<String>() {
@Override
public boolean test(String s) {
return "test".equals(s);
}
};
test(predicate, "这是jdk1.7的写法");
/**
* 1.8
*/
test(str -> "test".equals(str), "这是jdk1.8的写法");
}
/**
* 入参为Predicate<T>的方法
*
* @param predicate
* @param str
* @return
*/
public static boolean test(Predicate<String> predicate, String str) {
return predicate.test(str);
}