函数式接口-lambda,优雅开发代码

JDK中现在有很多Functional Interface这个特性用来代替我们传统的匿名内部类写法, 传统我们使用

  1. 实例化接口
  2. 重写接口内对应的方法 来帮助我们实现,但这种方法代码冗杂,而且也不好看。
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]Tvoidaccept(T)消费型
Supplier[T]voidTT get()供给型
Function[T,R]TRR apply(T)函数型
Predicate[T]Tbooleanboolean test(T)判断型

大致根据类型就是这几种,Function包内部还有一些扩展的,比如DoubleConsumer,入参从泛型变为double等;

总结:

Functional Interface帮助我们开启函数式编程,在很多包内也加入了对应使用,比如list的forEach、Stream包等、Optional包等内部方法都使用了函数式接口作为方法,让我们在方法体内部调用我们想要的逻辑;

end
  • 作者:Endwas(联系作者)
  • 发表时间:2021-04-07 15:44
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转博主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者名字和博客地址
  • 评论