Java8函数式接口
之前有关JDK8的Lambda表达式 Java代码(1)--Java8 Lambda
函数式接口可以理解就是为Lambda服务的,它们组合在一起可以让你的代码看去更加简洁
一、概念 |
1、什么是函数式接口
所谓函数式接口,当然首先是一个接口,然后就是在这个接口里面 只能有一个抽象方法
有关函数式接口,有个专门的注解叫 @FunctionalInterface ,该注解主要特点有:
1、该注解只能标记在“有且仅有一个抽象方法”的接口上,表示函数式接口 2、JDK8接口中的静态方法和默认方法,都不算抽象方法 3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中的方法,那么也不算抽象方法 4、允许java.lang.Object中的public方法 5、该注解不是必须的,如果一个接口符合‘函数式编程’定义,那么加不加该注解都没有影响,加上该注解能够让编译器更好的检查,如果编写的不是函数式接口,但是加上了@FunctionalInterface那么编译器会报错
正确示例
/** * 函数式接口注解 */ @FunctionalInterface public interface PersonInterface { /** * 1、仅有一个抽象方法 */ void say(); /** * 2、java.lang.Object中的方法不算 */ @Override boolean equals(Object object); /** * 3、java8接口才可以默认的方法实现,前提是方法名称必须使用default关键字修饰 */ default void defaultMethod(){ System.out.println("hello"); } /** * 4、静态方法 */ static void staticMethod(){ } }
错误示例
/** * 函数式接口注解 */ @FunctionalInterface //编译直接报错 public interface Test{ //1抽象方法 void say(); //2抽象方法 void jump(); }
加上@FunctionInterface,就代表该接口是函数式接口,只能有一个抽象方法,如果多个编译直接报错
3、为什么只能有一个抽象方法
其实这个问题很好去理解,上面说了函数式接口主要是为Lambda语法服务的,为了让代码看上去更简洁
下面通过示例来说明
public static void main(String[] args) { PersonInterface inter =() -> System.out.println("说什么呢?"); inter.say(); //输出:说什么呢? }
通过函数式接口+Lambda表达式让代码看上去变得简洁的,关键点在于
()->{} 就代表对say()方法的重写
如果有多个抽象方法,那么()->{ } 这种写法,编译器就不知道这个重写哪个方法了,所以这就是为什么只能有一个抽象方法的原因
二、综合示例 |
这里在举一个综合示例,来方便理解它们
自定义函数式接口
/** * 自定义函数TestFunction 提供handler接口,传入的是A,返回的是B * @param <A> * @param <B> */ @FunctionalInterface public interface MyFunction<A,B> { B handler(A a ,A a1); }
Student对象
@Data @AllArgsConstructor @ToString public class Student { //姓名 private String name; //年龄 private Integer age; }
测试类
public static void main(String[] args) { //1.求和,传入integer返回integer类型 MyFunction<Integer,Integer> myFunction=(x,y)->{ return x+y; }; Integer count=myFunction.handler(5,10); System.out.println("输出总和为:"+count); //2、求和传入integer返回String类型 MyFunction<Integer,String> myFunction1=(x,y)->{ return x+"+"+y+"="+(x+y); }; System.out.println(myFunction1.handler(5,10)); //3、对象处理过滤对象 List<Student> students= Arrays.asList(new Student("小明",3),new Student("小白",13),new Student("小黄",19)); MyFunction<Integer,List<Student>> myFunction2=(x,y)->{ List<Student> studentList=students.stream().filter(student -> student.getAge()>x && student.getAge()<y).collect(Collectors.toList()); return studentList; }; List<Student> list=myFunction2.handler(5,15); list.forEach(x-> System.out.println(x)); }
运行结果:
从运行结果可以很明显看出,集合对象经过过滤只剩下一个满足条件的了。