java函数式接口看这一篇就够了 -ag凯发k8国际
目录:
1.函数式接口的基本概念和格式
2.函数式编程
3.函数式接口作为方法的参数和方法的返回值
4.常用函数式接口
1.函数式接口的基本概念:
函数式接口在java中是指:有且仅有一个抽象方法的接口。
函数式接口,即适用于函数式编程场景的接口。而java中的函数式编程体现就是lambda,所以函数式接口就是可 以适用于lambda使用的接口。只有确保接口中有且仅有一个抽象方法,java中的lambda才能顺利地进行推导。
如果对lambda表达式不是很清除那么可以参照这一篇博客:lambda表达式详解
介绍一个语法糖概念:
语法糖:是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,其实 底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,java中的lambda可以被当做是匿名内部 类的“语法糖”,但是二者在原理上是不同的。
2.格式:
只要满足有一个抽象方法的接口即可,当然也可以包含其他的方法(默认静态私有等等)
修饰符 interface 接口名称{ (public abstract) 返回值类型 方法名称(可选参数信息); // 其他非抽象方法内容 }由于接口中默认类型为public abstract 所以带不带都行
3.@functionalinterface注解:
java 8中专门为函数式接口引入了一个新的注解: @functionalinterface。该注 解可用于一个接口的定义上
@functionalinterfacepublic interface myfunctionalinterface{ void mymethod(); }我们这一个注解当我们在定义函数式接口的时候发送了错误,那么注解的编译就不通过:
当我们去掉一个抽象的方法的时候就,注意就会正常通过编译:
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。需要注 意的是,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
1.lambda表达式的延迟执行
看一段代码:
分析一下这段代码,发现存在浪费,首先log方法传进两个参数,第一个参数是一个数字,第二个参数是一个拼接后的字符串,那么正常调用的时候我们就要先把字符串拼接好后再调用log函数,如果第一个参数不是1,那么拼接字符串就显得没用,白拼接了,这样就造成了浪费,这时候就可以使用lambda解决
想要解决问题,那么首先我们了解lambda的使用特点和前提:
1.使用特点:延迟加载
2.使用前提:必须存在函数式接口
具体解决的代码实现:
package untl1; public class demo02loggerlambda {private static void log(int level, messagebuilder builder){if (level == 1){system.out.println(builder.buildmessage());}}public static void main(string[] args){string msga = "hello";string msgb = "world";string msgc = "java";log(1, ()-> msgamsgbmsgc);} } @functionalinterface interface messagebuilder {string buildmessage(); }此段代码就完美的解决上述问题,那么,我们如何证实在第一个参数不是1的时候不进行字符串的拼接呢,我们可以在第二个参数加一个书输出语句即
package untl1; public class demo02loggerlambda {private static void log(int level, messagebuilder builder){if (level == 1){system.out.println(builder.buildmessage());}}public static void main(string[] args){string msga = "hello";string msgb = "world";string msgc = "java";log(1, ()-> {system.out.println("我第一个参数是1");return msgamsgbmsgc1;});log(2, ()-> {system.out.println("我第一个参数不是1");return msgamsgbmsgc2;});} } @functionalinterface interface messagebuilder {string buildmessage(); } 运行结果: 我第一个参数是1 helloworldjava1作为方法的参数,上边修正过的例子就是,作为方法的返回值如下例:
package untl1; public class demo02loggerlambda {private static messagebuilder log(){return (a,b)->{return ab;};}public static void main(string[] args){messagebuilder a=log();system.out.println(a.buildmessage("hello","world"));} } @functionalinterface interface messagebuilder {string buildmessage(string a,string b); } 运行结果: helloworld注意return中的a和b是两个变量名称,可以随意更改
1.supplier接口:
(1) 简介:
java.util.function.supplier
(2)例子:
package untl1; import java.util.function.supplier; public class mysupplier {public static string getstring(supplier<string> sup){return sup.get();}public static void main(string[] args) {string str=getstring(()->"helloworld");system.out.println(str);}} 运行结果: helloworld2.consumer接口:
(1)简介:
java.util.function.consumer
(2)l例子:
package untl1; import java.util.function.consumer; public class myconsumer {public static void method(string name, consumer<string> con){con.accept(name);}public static void main(string[] args) {method("我是帅哥",(string name1)-> system.out.println(name1));} }(3).consumer默认方法andthen
如果一个方法的参数和返回值全都是 consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作, 然后再做一个操作,实现组合。而这个方法就是 consumer 接口中的default方法 andthen 。下面是jdk的源代码:
default consumer<t> andthen(consumer<? super t> after) { objects.requirenonnull(after);return (t t) ‐> {accept(t); after.accept(t); }; }其实andthen方法简单来说就是把两个consumer接口组合在一起,在分别对数据进行消费
下面我们不使用andthen和使用andthen的两个例子做对比:
例子1(不使用andthen):
我们使用andthen之后:
package untl1; import java.util.function.consumer; public class myconsumer {public static void method(string str, consumer<string> a,consumer<string> b){a.andthen(b).accept(str);}public static void main(string[] args) {method("hello",(string a)-> system.out.println(a),(string b)-> system.out.println(b.touppercase()));}} 运行结果和上边的一样上述代码由于是a连接b那么先执行a消费数据,然后再执行消费数据
3.predicate接口:
(1)简介;
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用 java.util.function.predicate
(2)例子:
package untl1; import java.util.function.predicate; public class mypredicate {public static boolean checkstring(string str, predicate<string> pre){return pre.test(str);}public static void main(string[] args) {string str="abc";boolean b=checkstring(str,a->a.length()>6);system.out.println(b);} } 运行结果: false(3)默认方法and:
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个 predicate 条件使用“与”逻辑连接起来实 现“并且”的效果时,可以使用default方法 and。其jdk源码为
default predicate<t> and(predicate<? super t> other) {objects.requirenonnull(other);return (t) ‐> test(t) && other.test(t); }例子:
我么判断一个字符串里边长度是不是为5,里边是不是包含a这个字符:
(4)默认方法or:
与 and 的“与”类似,默认方法 or 实现逻辑关系中的“或”。
例子:
package untl1; import java.util.function.predicate; public class mypredicate {public static boolean checkstring(string str, predicate<string> a,predicate<string> b){return a.or(b).test(str);//其实就相当于return a.test(str)||b.test(str)}public static void main(string[] args) {boolean a= checkstring("abc",str->str.length()==5,str->str.contains("a") );system.out.println(a);} } 运行结果: true(5)默认方法negate:
“或”已经了解了,剩下的“非”(取反)也会简单。
例子:
package untl1; import java.util.function.predicate; public class mypredicate {public static boolean checkstring(string str, predicate<string> a){return a.negate().test(str);}public static void main(string[] args) {boolean a= checkstring("abc",str->str.length()==5);system.out.println(a);} } 运行结果: true5.function接口:
(1)简介
java.util.function.function
(2)
例子:
(3)默认方法andthen:
同样进行组合操作:
例子:
我们把string类型的123转换成integer加上10,再转换成string类型:
总结
以上是ag凯发k8国际为你收集整理的java函数式接口看这一篇就够了的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: what?java这么神奇的lambda
- 下一篇: java方法的引用(打造lambda表达