JDK中现在有很多Functional Interface这个特性用来代替我们传统的匿名内部类写法, 传统我们使用
- 实例化接口
- 重写接口内对应的方法 来帮助我们实现,但这种方法代码冗杂,而且也不好看。
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "onClick", Toast.LENGTH_SHORT).show();
}
});
所以Java8新增了Functional Interface函数式接口,他的特点是只有一个抽象方法,这个特点帮助我们在传参的时候,编译器就能知道我们实现的是哪个方法,根据对应的格式编写lambda表达式就可以了,开发简单易懂。
相信大家看到这里还是不知道有什么用,也看不懂,没关系我们看个例子
1. 定义和使用
这个接口你需要确定,1.是否需要参数,是可以任意类型参数(泛型)还是特一具体类型;2.是否需要返回值,返回值是任意类型还是固定如boolean;
- 定义了一个Animal接口,入参String,返回值void,我们在使用这个方法时要按照这个标准!
@FunctionalInterface
public interface Animal {
void eat(String food);
}
- 定义了个方法lunch,需要传入上面的Functional Interface作为入参;
- 在lunch方法体内部任何你想要的地方调用该eat抽象方法;
static void lunch(Animal animal) {
System.out.println("animal is eating");
animal.eat("hao chi!");
System.out.println("animal have had lunch");
}
- 这样我们就可以用lambda表达式来实现该具体接口方法了;
- 遵循抽象方法规范:一个入参,我们把这个入参定义名为message,无返回值即没有return;
public class main {
public static void main(String[] args) {
lunch(message -> {
message += "大吃一顿";
System.out.println(message);
});
}
}
2.JDK中定义的函数式接口
1. Runnable类
特点:无入参,无返回值
@FunctionalInterface
public interface Runnable {
void run();
}
Runnable r = ()->{
System.out.println("this is runnable interface");
};
new Thread(r).start();
2. Callable类
特点:无入参,有返回值V
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Callable c = ()-> "callable.class";
Future submit = Executors.newSingleThreadExecutor().submit(c);
Optional.of(submit).ifPresent(o->{
try {
System.out.println(o.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
3.Function类
特点:有入参T,有返回值R
@FunctionalInterface
public interface Function<T, R> {
R apply(T var1);
}
4.Consumer类
特点:有入参T,无返回值
@FunctionalInterface
public interface Consumer<T> {
void accept(T var1);
}
5.Supplier类
特点:无入参,有返回值T
@FunctionalInterface
public interface Supplier<T> {
T get();
}
6.Predict类
特点:有入参T,有返回值boolean
@FunctionalInterface
public interface Predicate<T> {
boolean test(T var1);
}
接口名 | 输入类型 | 输出类型 | 核心方法 | 说明 |
---|---|---|---|---|
Consumer[T] | T | void | accept(T) | 消费型 |
Supplier[T] | void | T | T get() | 供给型 |
Function[T,R] | T | R | R apply(T) | 函数型 |
Predicate[T] | T | boolean | boolean test(T) | 判断型 |
大致根据类型就是这几种,Function包内部还有一些扩展的,比如DoubleConsumer,入参从泛型变为double等;
总结:
Functional Interface帮助我们开启函数式编程,在很多包内也加入了对应使用,比如list的forEach、Stream包等、Optional包等内部方法都使用了函数式接口作为方法,让我们在方法体内部调用我们想要的逻辑;
评论