Java函数式接口定义
Java函数式接口,英文名Functional Interface,就是有且仅有一个抽象方法的接口,但是可以有多个非抽象方法的接口,就是函数式接口。
Java Lambda就是Java中函数式编程的体现,可以使用Lambda表达式创建一个函数式接口的对象。
Java函数式接口语法
Java函数式接口格式:只要确保接口中有且仅有一个抽象方法即可。
语法:
修饰符 interface 接口名称 { public abstract 返回值类型 方法名称(可选参数信息); // 其他非抽象方法内容 }
示例:
@FunctionalInterface public interface Runnable { public abstract void run(); }
这个就一个函数式接口。
@FunctionalInterface注解
Java 8中专门为函数式接口引入了一个新的注解: @FunctionalInterface 。
该注 解可用于一个接口的定义上:
@FunctionalInterface public interface MyFunctionalInterface { void myMethod(); }
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。
需要注 意的是:即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
Java函数式接口使用
1.新建一个 MyInterface 函数式接口
示例如下:
/** * @author mikechen */ @FunctionalInterface public interface MyInterface { void mikechensay(); }
2.使用匿名内部类的方式来进行使用
示例如下:
/** * @author mikechen */ public class Main { public static void main(String[] args) { MyInterface myInterface = new MyInterface() { @Override public void mikechensay() { System.out.println("hello 函数式接口"); } }; myInterface.mikechensay(); } }
3.还可以使用 Java Lambda 表达式简化使用
示例如下:
/** * @author mikechen */ public class Main { public static void main(String[] args) { MyInterface myInterface = () -> System.out.println("函数式接口"); myInterface.mikechensay(); } }
Java函数式接口的应用
1.作为方法的参数
public class Main { public static void main(String[] args) { startThread(() -> System.out.println("线程启动")); } private static void startThread(Runnable runnable) { new Thread(runnable).start(); }
2.作为方法的返回值
public class Main { public static void main(String[] args) { List<String> array = new ArrayList<>(); array.add("BNTang"); array.add("Jonathan_Lee"); array.add("bbb"); array.add("aa"); array.add("cccc"); System.out.println("排序前" + array); Collections.sort(array); System.out.println("排序后" + array); Collections.sort(array, getComparator()); } private static Comparator<String> getComparator() { Comparator<String> comp = new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.length() - s2.length(); } }; return (String s1, String s2) -> { return s1.length() - s2.length(); }; } }
Java函数式接口示例
public class FunctionalInterfaceTest { // 1.写了一个方法,参数是函数式接口,你可以传递Runnable的实现,也可以使用Lambda或方法引用 public static void execute(Runnable runnable) { try { runnable.run(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { // 2.传入匿名对象 execute(new Runnable() { @Override public void run() { System.out.println("匿名对象"); } }); // 3.使用Lambda,()表示Runnable#run()的参数,println()是Runnable#run()的方法体 execute(() -> System.out.println("使用lambda")); // 5.因为wrapPrintln和上面的println做的是同样的事,可以替换 UserService userService = new UserService(); execute(() -> userService.wrapPrintln()); // 6.IDEA提示上面的代码可以优化成 方法引用 execute(userService::wrapPrintln); // 8.你会发现上面的写法仍是对的,因为“仅有一个抽象方法”是对Runnable的约束,不要搞混 } // 4.我们试着把println()移到wrapPrintln中 static class UserService { public void wrapPrintln() { System.out.println("包装后的println"); } // 7.给UserService新增一个方法 public void anotherMethod() { System.out.println("另一个方法,不影响execute使用wrapPrintln"); } } }
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》