“这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
jdk8接口新特性
上一次写到 :juejin.cn/post/699927… 用lambda表达式写了一个接口,并写了4个示例
interface Interface1{
int doubleNum(int i);
}
public static void main(String[] args) {
Interface1 i1 = (i) ->i * 2;
//最常见写法
Interface1 i2 = i->i*2;
Interface1 i3 = (int i)->i*2;
Interface1 i4= (int i)->{
System.out.println("----");
return i*2;
};
}
那么我们队接口有么有什么限制呢,就是接口里面有且只有一个要实现的方法(doubleNum)
这是java8新引入的 概念叫:函数接口 @FunctionalInterface
如果加了注解之后继续写实现的话,就会报错
进入jdk8之后,我们需要将接口设计的小,这就是单一责任制。 我们实际设计接口的时候,也要尽量设计的细一点,尽量每个接口只做一个事,而且接口可以多继承,我们可以最后写一个类,一个接口来继承这些接口,更细的接口可以让我们用lambda更方便
所以 @FunctionalInterface 还是要尽量加一下
lambda 表达式要实现的接口仅有一个,不代表里面的实现只有一个, 虽然
int doubleNum(int i);
int doubleNum2(int i2);
是报错的 但是默认实现的是不管的
@FunctionalInterface
interface Interface1{
int doubleNum(int i);
default int add(int x,int y){
return x+y;
}
}
public static void main(String[] args) {
Interface1 i1 = (i) ->i * 2;
i1.add(5,5);
System.out.println(i1.doubleNum(20));
}
接口多重继承方法,default方法覆盖的场景 首先我们复制Interface1 为 Interface2
@FunctionalInterface
interface Interface1{
int doubleNum(int i);
default int add(int x,int y){
return x+y;
}
}
@FunctionalInterface
interface Interface2{
int doubleNum(int i);
default int add(int x,int y){
return x+y;
}
}
然后 Interface3 同时继承 前面2个接口
发现程序无法知道我们要默认实现 Interface2 还是 Interface1 ,是add 还是 doubleNum
我们执行 Interface2的 add接口
@FunctionalInterface
interface Interface3 extends Interface2,Interface1{
@Override
default int add(int x, int y) {
return Interface1.super.add(x, y);
}
}
得到以上结果
jdk8的函数接口,这些接口好用还好学
写一个印钱程序
使用函数式接口之前
interface IMoneyFormat{
String format(int i);
}
class MyMoney{
private final int money;
public MyMoney(int money){
this.money = money;
}
public void printMoney(IMoneyFormat moneyFormat){
System.out.println("我的存款"+ moneyFormat.format(this.money));
}
}
public class MoneyDemo {
public static void main(String[] args) {
MyMoney me = new MyMoney(9999999);
me.printMoney(i -> new DecimalFormat("#,###").format(i));
}
}
但是函数式接口并不关注你实现的接口,也就是说他不需要知道你的名字,也不需要知道你的方法只需要知道输入是什么,输出是什么
那我们就没必要总写接口,只要给一个输入是int类型 输出是String类型的函数Function<Integer,String>就OK 了 。
class MyMoney{
private final int money;
public MyMoney(int money){
this.money = money;
}
public void printMoney(Function<Integer,String> moneyFormat){
System.out.println("我的存款"+ moneyFormat.apply(this.money));
}
}
public class MoneyDemo {
public static void main(String[] args) {
MyMoney me = new MyMoney(9999999);
me.printMoney(i -> new DecimalFormat("#,###").format(i));
}
}
可以看出函数接口的好处就是不定义太多接口
第二个好处就是函数接口支持链式操作
public class MoneyDemo {
public static void main(String[] args) {
MyMoney me = new MyMoney(9999999);
Function<Integer,String> moneyFormat = i->new DecimalFormat("#,###").format(i);
//函数接口链式操作
me.printMoney(moneyFormat.andThen(s->"rmb"+s));
}
}
有输入无输出为 提供者,有输出无输入为消费者
演示
import java.util.function.Consumer;
import java.util.function.IntPredicate;
import java.util.function.Predicate;
public class FunctionDemo {
public static void main(String[] args) {
IntPredicate predicate = i->i>0;
//断言
System.out.println(predicate.test(-9));
//消费
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("输入的数据");
}
}