java8入门(二) --::和默认函数式接口

来源:互联网 发布:php curl添加头部信息 编辑:程序博客网 时间:2023/11/29 04:15
在上一篇λ表达式的文章中有提到,一个接口未实现方法,有3种途径可以使用,实际上还有一种途径可以使用,也就是java8推出的::,这个是什么呢,就叫它方法引用吧。来看下是怎么操作的先。比如有一个与接口毫无关联的类Third,代码如下
package help.mygod.java8;public class Third {    public String getNameById(String id){        if("003".equals(id)){            return "xiao san";        }else {            return "normal";        }    }}

然后我正在一边使用接口开发,我的接口是这样子的

package help.mygod.java8;@FunctionalInterfacepublic interface IStudent {    String getName(String id);    default void printName(){        System.out.println("I student");    }}

我准备用λ表达式来实现这个方法,大概就是如果学号是003的,那她就是小三,其它的就是正常的,好吧,这个应该很快写出来,但我一看,旁边有个毫无关联类的方法正好和我想写的方法一样,入参,返回参数都匹配,虽然方法名不一样,那我能不能直接用它呢,答案是可以的。如下

package help.mygod.java8;public class Main {    public static void main(String[] args) {        // 3,λ表达式        printName(id -> {            if ("007".equals(id))                return "William";            else                return "Moss";        }, "007");        Third t = new Third();        //4,别人家的方法        printName(t::getNameById, "007");    }    public static void printName(IStudent student, String id) {        System.out.println(student.getName(id));    }}

看到了吧。只要入参和出参一样,方法就可以到处引用。这个和方法调用差不多,静态的前面可以用类名,非静态则前面是用实例名。所以这个就是方法引用。很多人会混淆引用和调用。引用就是把方法内容传过去,调用就是执行方法,得到结果了。

然后,不知道大家注意了到了没有,无论是λ表达式还是::,方法名都显得无关紧要了,入参和出参才是最重要的。 我这边还有一个接口,大概是想实现通过小孩的名称而找到父亲的名称,代码如下

package help.mygod.java8;public interface IKingdom {    String getFatherName(String childName);}

然后调用客户端的代码如下:

package help.mygod.java8;public class Main {    public static void main(String[] args) {        // 3,λ表达式        printName(id -> {            if ("007".equals(id))                return "William";            else                return "Moss";        }, "007");        Third t = new Third();        //4,别人家的方法        printName(t::getNameById, "007");        //通过小孩姓名找父亲姓名        printFatherName(childName -> {            if("xiaoming".equals(childName))                return "daming";            else                return "dahong";        },"xiaoming");    }    public static void printName(IStudent student, String id) {        System.out.println(student.getName(id));    }    public static void printFatherName(IKingdom kingdom, String childName) {        System.out.println(kingdom.getFatherName(childName));    }}

如果还有很多类似的方法,通过传入一个String,又返回一个String的,是不是有很多大量类似的代码呢。既然方法名又不重要,为什么不起一些通用的名字,而大家都用一个接口呢,所以方法改造如下,先是接口

package help.mygod.java8;public interface ICommon <T> {    T getName(T t);}

调用代码如下:

package help.mygod.java8;public class Main {    public static void main(String[] args) {        // 3,λ表达式        printName(id -> {            if ("007".equals(id))                return "William";            else                return "Moss";        }, "007");        getName(id -> {            if ("007".equals(id))                return "William";            else                return "Moss";        }, "007");        Third t = new Third();        //4,别人家的方法        printName(t::getNameById, "007");        //通过小孩姓名找父亲姓名        printFatherName(childName -> {            if("xiaoming".equals(childName))                return "daming";            else                return "dahong";        },"xiaoming");        getName(childName -> {            if("xiaoming".equals(childName))                return "daming";            else                return "dahong";        },"xiaoming");    }    public static void printName(IStudent student, String id) {        System.out.println(student.getName(id));    }    public static void printFatherName(IKingdom kingdom, String childName) {        System.out.println(kingdom.getFatherName(childName));    }    public static void getName(ICommon common,String key){        System.out.println(common.getName(key));    }}

哈哈,看到了吧。getName执行的结果是一样的。所以java8可以根据入参和出参就能封装。可以省略很多代码。所以,同学们,开始封装吧,哦,等等。因为这封装也太显眼了,所以java8说,干脆我替你们封装吧。所以就根据入参和出参封装了一系列常用的接口,也叫默认函数式接口吧。这里就列举一些常用的,大家要用的时候就查吧。

Predicate 接口只有一个参数,返回boolean类型。
Function 接口有一个参数并且返回一个结果。
Supplier 接口返回一个任意范型的值,和Function接口不同的是该接口没有任何参数。
Consumer 接口表示执行在单个参数上的操作。
。。。。。。

0 0