ja接口

函数式编程是一种编程规范或编程思想。很容易理解,把操作或实现过程看成是函数的计算。为了实现函数式编程,Ja8提出了三个重要概念:Lambda表达式、方法引用和函数接口。现在很多公司都在用lambda表达式来编码,甚至知名的Ja插件都在Lambda里,比如数据库插件MybatisPlus。lambda表达式的使用需要函数接口的支持,即Lambda表达式的核心是使用大量的函数接口。本文将引导您全面理解功能接口的定义和使用。

一、文章导读函数式接口概述自定义函数式接口常用函数式接口函数式接口的练、函数式接口概述1.函数式接口定义

如果接口中只有一个抽象方法,那么它就是一个函数接口。可以使用注释(@FunctionalInterface)来检查接口是否是函数接口,即只能有一个抽象方法。

需要注意的事项

可以在函数接口中定义默认方法:默认方法有方法体,不是抽象方法,符合函数接口的定义要求。可以在函数接口中定义静态方法:静态方法不是抽象方法,而是有具体方法的方法,也符合函数接口的定义。Object中的公共方法可以在函数接口中定义(改为抽象方法):虽然是抽象方法,但不需要覆盖,因为所有接口的实现类都是Object类的子类,这些方法在Object类中都有具体的实现。2.函数接口格式修饰符接口名称{//抽象方法公共抽象返回值类型方法名称(可选参数信息);//默认方法公共默认返回值类型方法名称(可选参数信息){/code…}/Static method公共静态返回值类型方法名称(可选参数信息){/code…}//对象类的公共方法变成抽象方法公共抽象布尔等于(object obj);公共抽象字符串toString();}三、自定义功能界面1。自定义函数接口的例子因为接口中抽象方法的公共抽象可以省略,所以定义函数接口非常简单:

@ functional Interface public Interface my functional Interface {//抽象方法公共抽象void方法();//对象类的公共方法变成抽象方法公共抽象布尔等于(Object obj);公共抽象字符串toString();//Default方法public Default void show(strings){//打印小写系统。out.println (s.to小写());}//静态方法public static void print(strings){//打印大写系统。out . println(s . toupper case());}}2.自定义功能接口的应用对于新定义的MyFunctionalInterface功能接口,使用典型的使用场景作为方法的参数:

公共类demo01函数接口{ public static void main(string[]args){//调用方法show(()-& gt;{ system . out . println(& # 34;Lambda执行& # 34;);});}//定义方法使用函数接口作为参数public static void show(我的函数接口MFI){//调用自己定义的函数接口MFI . method();string s = MFI . tostring();system . out . println(s);布尔结果= MFI . equals(MFI);System.out.println(结果);MFI . show(& # 34;世界& # 34;);myfunctionalinterface . print(& # 34;功能& # 34;);}}3.运行结果:Lambda执行的DEMO 01函数接口$ Lambda $ 1/1078694789 @ 3d 075 DC 0 rueworldfunction IV。常用的功能接口我们自己定义了一个功能接口。对于一些常用的功能接口,每次都要自己定义,非常麻烦。JDK提供了大量常用的函数接口来丰富Lambda的典型使用场景,主要在ja.util.function包中提供。有许多这样的接口,下面是最简单的接口和它们的使用示例。1.供应商接口ja.util.function .供应商

1.1.抽象方法 : get

Supplier的接口包含一个抽象方法T get():它用于获取由泛型参数指定的类型的对象数据。public class demo 02 supplier { public static void main(String[]args){ int num = getNum(()-& gt;{返回新的Random()。nextInt();});system . out . println(num);} public static int getNum(Supplier & lt;整数& gtsupplier){ int num = supplier . get();退货数量;}}1.2.求集合元素的最大值。使用Supplier接口作为方法参数类型,通过Lambda表达式找到列表集中的最大值(存储int数据)。提示:请使用ja.lang.Integer类作为接口的泛型。

代码示例:

public class demo 03 supplier { public static void main(String[]args){ List & lt;整数& gtlist = new ArrayList & lt& gt();Collections.addAll(list,10,8,20,3,5);print max(()-& gt;{ return collections . max(list);});}私有静态void printMax(供应商& lt整数& gtsupplier){ int max = supplier . get();system . out . println(max);}}2.消费者接口ja.util.function.consumer另一方面,接口不产生数据,而是使用其数据类型由泛型参数确定的数据。

2.1.抽象方法:accept

消费者接口包含抽象方法void accept(T t):消费指定的通用数据。

代码示例:

导入Ja . util . function . consumer;//接收一个输入参数X,将X的值放大2倍,然后用+3//输出类似数学中的函数:f(X)= 2 * X+3 public class demo 04 consumer { public static void main(string[]args){ int X = 3;consumeIntNum(x,(整数)-& gt;{ system . out . println(2 * num+3);});}/*定义方法,使用函数接口Consumer作为方法参数*/private static void consume int num(int num,consumer < Integer & gtfunction){ function . accept(num);}}2.2.默认方法:然后如果一个方法的参数和返回值都是消费者类型,就可以达到这样的效果:在消费一条数据的时候,先做一个操作,再做另一个操作实现组合。这个方法是默认方法,然后在用户界面中使用。以下是JDK的源代码:

默认消费者& ltT & gt然后(消费者& lt?超级T & gtafter){ objects . require nonnull(after);return(T T)-& gt;{接受(t);接受(t);};}注意:require nonNull Ja . util . objects的静态方法在参数为null时会主动抛出一个NullPointerException。这样就省去了反复写if语句和抛出空指针异常的麻烦。然后是默认方法,由消费者的对象调用,参数和返回值都是消费者对象。

要实现组合,需要两个或更多的Lambda表达式,and的语义则是“逐步”操作。例如,在结合两个步骤的情况下:

代码示例:

//接收一个字符串,先大写打印,再小写/* toUpperCase():将字符串改为大写toLowerCase():将字符串改为小写*/public class demo 05 consumer { public static void main(string[]args){ strings = & # 34;你好& # 34;;//lambda标准格式fun (s,(string str)->;{ system . out . println(s . toupper case());}、(字符串str)->;{ system . out . println(s . tolowercase());});}/*定义方法,参数是消费者接口。因为需要消费两次,所以需要两个消费者接口作为参数*/public static void fun (strings,Consumer

为了让大家更容易理解,我们先用andThen的方法来演示一下。

public class demo 06 consumer { public static void main(String[]args){ String s = & # 34;HelloWorld & # 34;//2.lambda标准格式fun(s,(String str)-& gt;{ system . out . println(s . toupper case());}、(字符串str)->;{ system . out . println(s . tolowercase());});}/*定义方法,参数是消费者接口。因为需要消费两次,所以需要两个消费者接口作为参数*/public static void fun (strings,Consumer

然后是原理分析图:

java接口

注意:1.con1调用andThen方法并传递参数con2,所以这个在anThen方法里面是con1,CON 1,后面是CON 22。andThen方法调用accept方法,前面隐藏了一个this,表示调用AND THEN方法的对象,this,this,CON 13。THEN方法里面的T是谁?接受(t)

3.1.抽象方法:apply

函数接口中主要的抽象方法是:R apply(T t),根据T类型的参数得到R类型的结果。

代码示例:

将字符串类型转换为整数类型。

/* Ja . util . function . function & ltt,R & gt:可转换接口泛型T:转换前的类型泛型R:转换后的类型抽象方法:Apply (t t):根据T类型的参数获取R类型的结果,将参数T转换为R类型的结果& # 34;123"-& gt;123要求:给你一个String类型的数,给我转换成int数。分析:使用函数接口T:转换前的类型,String R:转换后的类型,integer */public class demo 07 Function { public static void main(String[]args){ String = & # 34;123";//lambda标准格式fun (s,(string str)->;{ return integer . parse int(str);});}/*定义方法,使用函数接口作为参数*/public static void fun (strings,Function

默认& ltV & gt函数& ltt,V & gt然后(函数& lt?超级R,?扩展V & gtafter){ objects . require nonnull(after);return(T T)-& gt;after . apply(apply(t));}这种方法也用在“先做什么,再做什么”的场景中,类似于《消费者》中的andThen:

代码示例:

把String的个数转换成int的个数,然后把int的个数放大10倍。

/* Ja . util . function . function & ltt,R & gt:可转换接口泛型T:转换前类型泛型R:转换后类型默认方法:默认;{ return integer . parse int(str);},(整数)-& gt;{ return num * 10});}/*定义一个有两个函数接口作为参数的方法*/public static void fun (strings,Function

请注意,函数的前置条件泛型和后置条件泛型可以是相同的。

为了让大家更容易理解,我们先用andThen的方法来演示一下。

public class demo 09 function { public static void main(String[]args){ String s = & # 34;123";//lambda标准格式fun (s,(string str)->;{ return integer . parse int(str);},(整数)-& gt;{ return num * 10});}/*定义一个有两个函数接口作为参数的方法*/public static void fun (strings,Function

然后是原理分析图:

注意:1.fun1调用andThen方法传递参数fun2,所以这个在andThen方法里面是fun1,fun1,after是fun22。andThen方法直接调用apply方法,前面隐藏了一个this,代表调用andthen方法的对象,this,this,fun2 2.andThen方法里面的T是谁?这是。应用(t)

4.1.抽象方法:test

谓词接口包含一个抽象方法:布尔测试(T t)。条件判断的场景:

//1.练习:判断字符串的长度是否大于5//2。练习:判断字符串是否包含& # 34;H & # 34public class demo 10 predicate { public static void main(String[]args){ String str = & # 34;helloWorld & # 34;//1.练习:判断字符串长度是否大于5 //lambda标准格式fun (str,(strings)->;{ return s . length()& gt;5;});system . out . println(& # 34;- ");//2.练习:判断一个字符串是否包含& # 34;H & # 34//lambda标准格式fun (str,(strings)->;{ return s . contains(& # 34;H & # 34);});}/*定义一个方法,参数是predict interface */public static void fun(strings,predict

4.2.默认方法:and

既然是条件判断,那么就会出现与、或、非三种常见的逻辑关系。当两个谓词条件通过and逻辑连接以达到AND的效果时,可以使用默认方法AND。它的JDK源代码是:

默认谓词& ltT & gtand(谓词& lt?超级T & gtother){ objects . require nonnull(other);return(t)-& gt;测试(t)和其他测试(t);}代码示例:

判断一个字符串应该同时包含大写字母“H”和大写字母“W”

public class demo 11 predicate { public static void main(String[]args){ String str = & # 34;HelloWorld & # 34;//1.练习:判断一个字符串是否应该同时包含大写“h”和大写“w”//lambda标准格式fun 1 (str,(strings)-> { return s . contains(& # 34;H & # 34);}、(字符串s)-& gt;{ return s . contains(& # 34;W & # 34);});system . out . println(& # 34;- ");fun 2(String,(String s)->{ return s . contains(& # 34;H & # 34);}、(字符串s)-& gt;{ return s . contains(& # 34;W & # 34);});}/*演示和方法需要两个谓词作为参数。fun1方法不使用and方法,即p1和p2分别调用test方法,然后对结果进行&&运算——其实这就是and方法*/public static void fun (strings,predict

默认谓词& ltT & gtor(谓词& lt?超级T & gtother){ objects . require nonnull(other);return(t)-& gt;test(t)| other . test(t);}代码示例:

字符串包含一个大写的h或一个大写的w “

public class demo 12 predicate { public static void main(String[]args){ String str = & # 34;Helloworld & # 34;//1.练习:判断一个字符串包含大写“h”还是大写“w”//lambda标准格式fun 1 (str,(strings)-> { return s . contains(& # 34;H & # 34);}、(字符串s)-& gt;{ return s . contains(& # 34;W & # 34);});system . out . println(& # 34;- ");fun 2(String,(String s)->{ return s . contains(& # 34;H & # 34);}、(字符串s)-& gt;{ return s . contains(& # 34;W & # 34);});}/* Demonstrator方法需要两个谓词作为参数。fun1方法不使用or方法,即p1和p2分别调用test方法,然后对结果执行||运算——其实这就是or方法的底层实现*/public static void fun (strings,predict

4.4.默认方法:negate

“和”和“或”已经理解了,剩下的“不是”(否定)就简单了。默认方法“求反”的JDK源代码是:

默认谓词& ltT & gtnegate(){ return(t)-& gt;!测试(t);}从实现中很容易看出它是为了“!”执行测试方法后的结果布尔值。取而代之。确保在调用test方法之前调用negate方法,就像and和or方法一样:

导入Ja . util . function . predicate;public class demo 13 Predicate { private static void method(谓词& lt字符串& gtpredicate,String str){ boolean verlong = predicate . negate()。测试(str);system . out . println(& # 34;绳子长吗?"+very long);} public static void main(String[]args){ method(s-& gt;s . length()& lt;5, "Helloworld & # 34);五、小结本文通过具体的例子来演示函数接口的定义和使用。和公共功能接口。并给出了相关练习。对于一些函数接口中的默认方法,做了图形化的分析,让你更深入的理解函数接口的思想和用途。在以后的实际编程过程中,集合的操作都可以通过Stream flow来完成,Stream flow中很多方法的参数都是函数接口。通过本文的学习,你已经掌握了函数接口的使用,相信以后学习Stream flow也是非常容易的。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论