当前位置: 首页 > 科技观察

系统综合了Java的所有特点,全面阐述了功能接口和应用

时间:2023-03-19 19:36:17 科技观察

技术的升级,往往不是独立的,而是系统的升级。升级的一小部分通常是修复BUG。JDK8的升级意义重大。环环相扣!本篇介绍的功能界面与上篇讲解的《??Lambda表达式??》紧密相关!在本文中,您只需要了解函数式接口的概念即可。写不写代码无所谓,很简单!掌握函数式接口的概念和含义。知道JDK内置函数式接口。函数式接口配合Lambda实现自定义函数式接口@FunctionalInterface注解。函数式接口是一种抽象方法,只有一个抽象方法,但可以有多个非抽象方法的接口是实现Lambda表达式的前提。您可以使用@FunctionalInterface注释来修改功能接口的含义。Java一直提倡面向对象。随着Python、Scala等语言的兴起和新技术的挑战,Java必须进行调整以支持更广泛的技术需求,所以Java不仅支持OOP【面向对象编程】,还支持OOF【面向函数编程]。以前需要通过匿名内部类来实现,现在可以通过Lambda来实现。实际上,Lambda表达式可以看作是一个函数式接口的实例。JDK内置函数式接口注:不用精通不用精通!看到网上很多资料只写了四个内置接口,比较局限。这里是对JDK内置接口的全面描述。你只需要知道有这么多内置接口,而不是四个。JDK8中新引入的函数式接口:JDK8中新引入的函数式接口在java.util.function包下的作用如下:函数式接口参数类型返回类型目的Consumer消费接口Tvoid对T类型的对象进行操作,包括方法:Tt)SuppliersupplyinterfacewithoutT返回一个T类型的对象,包括方法:Tget()Function功能接口TR对T类型的对象进行操作并返回结果。结果是一个R类型的对象。包含的方法:Rapply(Tt)Predicate断言类型接口Tboolean判断一个T类型的对象是否满足一定的约束条件,返回一个布尔值。包含方法:booleantest(Tt)BiFunctionT,UR对T、U类型的参数进行运算,返回R类型的结果。包含的方法是:Rapply(Tt,Uu)UnaryOperator(Functionsubinterface)TT对类型T的对象进行一元运算,返回类型T的结果。包含的方法是:Tapply(Tt);BinaryOperator(BiFunctionsub-interface)T,TT对T类型的对象进行二元运算,返回T类型的结果。包含方法为:Tapply(Tt1,Tt2);BiConsumerT,Uvoid将操作应用于T,U类型的参数。包含的方法是:voidaccept(Tt,Uu)BiPredicateT,Uboolean包含的方法是:booleantest(Tt,Uu)ToIntFunctionTint函数计算int值ToLongFunctionTlong函数计算long值ToDoubleFunctionTdouble函数计算double值IntFunctionintR参数是int类型函数LongFunctionlongR参数为long类型函数DoubleFunctiondoubleR参数为double类型函数JDK8之前的函数式接口:函数式接口在JDK8之前也有,JDK8升级后这些接口头用@FunctionalInterface修饰,如下:java.lang.Runnable【熟悉一下】用它,创建一个线程】java.util.concurrent.Callable【创建一个线程】java.security.PrivilegedAction【执行计算】java.util.Comparator【Lambda文章中提到的比较器】java。io.FileFilter[文件过滤器]java.nio.file.PathMatcher[路径匹配]java.lang.reflect.InvocationHandler[动态代理]java.beans.PropertyChangeListener[属性变化监听器]java.awt.event.ActionListener[事件监听器]javax.swing.event.ChangeListener[变化事件监听]Functional接口使用在上一篇文章中,我们使用了Runnable、Consumer、Supplier、Comparator等接口,这里我们将使用Function和Predicate接口。如果其他接口用到的时候,画葫芦画瓢就可以了!函数式接口接口定义如下:提示:接口中只有一个抽象方法的接口是函数式接口,与默认实现和静态方法无关。packagejava.util.function;importjava.util.Objects;/****@param输入参数类型*@param@FunctionalInterfacepublicinterfaceFunction{/**抽象方法:输入T类型参数,返回R类型T的值,R是泛型,请不要混淆*/Rapply(Tt);/**JDK8新特性,接口中可以有默认实现*/defaultFunctioncompose(Functionbefore){Objects.requireNonNull(before);返回(Vv)->应用(before.apply(v));}/**默认实现*/defaultFunctionandThen(Functionafter){Objects.requireNonNull(之后);返回(Tt)->之后。申请(申请(t));}/**JDK8接口的新特性:可以有静态方法*/staticFunctionidentity(){returnt->t;}}接口特点:一入一出,即一进一出,如果有传入一个参数返回一个参数的需求,可以使用该接口实现。需求:实现一个字符串转换函数,将所有输入的英文字符转换为大写并返回。分析:输入输出数据都是字符串,泛型都是String。接收调用apply方法计算后的返回值。代码实现:publicclassFunctionMain{publicstaticvoidmain(String[]args){//1.原始匿名内部类写法Functionfunction1=newFunction(){@OverridepublicStringapply(StringinputStr){//转换为大写returninputStr.toUpperCase();}};Stringresult=function1.apply("给我一个开始的机会!");System.out.println(结果);//2.Lambda表达式写法Functionfunction2=inputStr->inputStr.toUpperCase();StringlambdaResult=function2.apply("Lambda真的好香!");System.out.println(lambdaResult);}}Predicate接口接口定义:该接口也有默认实现和静态方法,但是只有一个抽象方法,所以也是一个函数式接口。packagejava.util.function;importjava.util.Objects;@FunctionalInterfacepublicinterfacePredicate{/**根据参数输入判断是否正确,返回true或false*/booleantest(Tt);默认Predicateand(Predicateother){对象。requireNonNull(其他);返回(t)->测试(t)&&其他。测试(t);}默认Predicatenegate(){return(t)->!test(t);}默认Predicateor(Predicateother){Objects.requireNonNull(other);返回(t)->测试(t)||其他.test(t);}staticPredicateisEqual(ObjecttargetRef){return(null==targetRef)?对象::isNull:对象->targetRef.equals(对象);计算后返回真或假。如果想做单参数判断,可以使用这个接口。Tips:Java中有两个Predicate类。不要导入错误的包。查找java.util.function包。当然,不要将此名称用于自定义类。[很多初学者喜欢用相同的名字来命名类]。需求:判断输入数据是否大于0。分析:泛型定义为Integer类型。可以通过判断返回结果。代码实现:publicclassPredicateMain{publicstaticvoidmain(String[]args){//1.原实现方法Predicatepredicate1=newPredicate(){@Overridepublicbooleantest(Integernum){returnnum>0;}};//调用测试方法booleanresult=predicate1.test(1024);System.out.println(结果);//2.Lambda表达式实现Predicatepredicate2=num->num>0;//调用测试方法booleanlambdaResult=predicate2.test(-1024);System.out.println(lambdaResult);}}Tips:对于这些默认方法的接口,使用时不要调用错方法即可!自定义函数式接口分析:函数式接口只有一个抽象方法,默认实现和静态方法不影响其作为函数式接口【JDK8支持带有默认方法和静态方法的接口】。接口可以抽象定义,所以我这里使用了泛型,可以根据自己的需要来定义。如果需要需要限制类型,也可以直接定义为特定类型。接口定义:packagecom.stt.function.myfunction;/***自定义函数式接口:*定义:*1.接口中只有一个抽象方法。*2.可以使用@FunctionInterface注解来修饰或者不使用。*如果使用这个注解报错,说明该接口不是函数式接口*/@FunctionalInterfacepublicinterfaceSttFunction{/***接收两个参数,返回一个参数*注:接口,只是大致定义一下即可,具体的参数以及如何返回就不用解释了。实现的时候再说吧*/Vcalc(Tt,Rr);}接口使用:packagecom.stt.function.myfunction;publicclassSttFunctionMain{publicstaticvoidmain(String[]args){//1.原始方式,匿名内部类实现SttFunctionsttFunction1=newSttFunction(){@OverridepublicIntegercalc(Integernum1,Integernum2){returnnum1*num2;}};整数结果=sttFunction1.calc(2,2);System.out.println(结果);//2.Lambda表达式调用SttFunctionsttFunction=(num1,num2)->num1+num2;;整数lambdaResult=sttFunction.calc(1023,1);System.out.println(lambdaResult);}}Lambda表达式是包含默认实现的函数式接口:包含默认方法和静态方法并不影响它是一个函数式接口。packagecom.stt.function.myfunction;/***自定义函数式接口:*定义:*1.接口中只有一个抽象方法。*2.可以使用@FunctionInterface注解修改,也可以不使用。*如果使用这个注解会报错,说明该接口不是函数式接口*/@FunctionalInterfacepublicinterfaceSttFunction{/***接收两个参数,返回一个参数*注意:对于接口,大致定义一下就可以了,具体有哪些参数,如何返回就不用解释了。实现的时候再说*/Vcalc(Tt,Rr);defaultvoiddefaultMethod(){System.out.println("不知道实现什么,反正JDK8以后可以有默认实现!");}staticvoidstaticMethod(){System.out.println("我也不知道写什么,反正JDK8以后可以有静态方法了!");}}抽象方法有多个:如果抽象方法超过两个,就不再是函数式接口,所以@FunctionalInterface注解会报错,可以用来判断接口是否是函数式接口。@FunctionalInterface注解Java8引入了一个专门用于函数式接口的新注解:@FunctionalInterface。这个注解放在接口上,表示这个接口是一个函数式接口。并提示编译器检查接口是否只包含一个抽象方法,即是否符合函数式编程的定义。Tips:如果自定义一个符合规范的函数式接口,也可以不加@FunctionalInterface注解。此注释仅用作提醒编译器执行规范检查。总结技术升级是系统性的,只是升级和修改其中的一部分,通常是修复bug。函数式接口是Lambda的前提。在JDK8之前,是通过匿名内部类实现的。Lambda使编码更简洁。函数式接口只有一个抽象方法。可以使用@FunctionalInterface或不使用来检查功能接口。JDK内置了很多函数式接口可以按需使用,我们也可以自定义函数式接口。阅读一些框架源码时一定要了解Lambda表达式和函数式接口。文章来自:田震,如需转载本文,请即日联系【田震】头条号。