@[toc]
@FunctionalInterface
函数式接口:有且只有一个抽象方法的接口,称之为函数式接口@FunctionalInterface注解作用:可以检测接口是否是一个函数式接口br/>@FunctionalInterface注解作用:可以检测接口是否是一个函数式接口
代码案例@FunctionalInterface
@FunctionalInterface public interface MyFunctionalInterface { /** * 定义一个抽象方法 */ public abstract void method(); } public class Demo { //定义一个方法,参数使用函数式接口MyFunctionalInterface public static void show(MyFunctionalInterface myInter){ myInter.method(); } public static void main(String[] args) { //调用show方法,方法的参数是一个接口,所以可以传递接口的实现类对象 show(new MyFunctionalInterfaceImpl()); //调用show方法,方法的参数是一个接口,所以我们可以传递接口的匿名内部类 show(new MyFunctionalInterface() { @Override public void method() { System.out.println("使用匿名内部类重写接口中的抽象方法"); } }); //调用show方法,方法的参数是一个函数式接口,所以我们可以Lambda表达式 show(()->{ System.out.println("使用Lambda表达式重写接口中的抽象方法"); }); //简化Lambda表达式 show(()-> System.out.println("使用Lambda表达式重写接口中的抽象方法")); } }输出如下:
使用匿名内部类重写接口中的抽象方法 使用Lambda表达式重写接口中的抽象方法 使用Lambda表达式重写接口中的抽象方法生产型接口Supplier
java.util.function.Supplier<T> 接口仅包含一个无参的方法:T get() 。用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
代码案例Supplier
获取一个字符串返回值:
public class Demo01Supplier { public static void main(String[] args) { //调用getString方法,方法的参数Supplier是一个函数式接口,所以可以传递Lambda表达式 String s = getString(()->{ //生产一个字符串,并返回 return "zjq666"; }); System.out.println(s); //优化Lambda表达式 String s2 = getString(()->"zjq666"); System.out.println(s2); } //定义一个方法,方法的参数传递Supplier<T>接口,泛型执行String,get方法就会返回一个String public static String getString(Supplier<String> sup){ return sup.get(); } }输出如下:
zjq666 zjq666求数组元素最大值:
public class Demo02Supplier { //定义一个方法,用于获取int类型数组中元素的最大值,方法的参数传递Supplier接口,泛型使用Integer public static int getMax(Supplier<Integer> sup){ return sup.get(); } public static void main(String[] args) { //定义一个int类型的数组,并赋值 int[] arr = {100,0,-50,880,99,33,-30}; //调用getMax方法,方法的参数Supplier是一个函数式接口,所以可以传递Lambda表达式 int maxValue = getMax(()->{ //获取数组的最大值,并返回 //定义一个变量,把数组中的第一个元素赋值给该变量,记录数组中元素的最大值 int max = arr[0]; //遍历数组,获取数组中的其他元素 for (int i : arr) { //使用其他的元素和最大值比较 if(i>max){ //如果i大于max,则替换max作为最大值 max = i; } } //返回最大值 return max; }); System.out.println("数组中元素的最大值是:"+maxValue); } }输出如下:
数组中元素的最大值是:880消费型接口Consumer
java.util.function.Consumer<T> 接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。Consumer 接口中包含抽象方法void accept(T t) ,意为消费一个指定泛型的数据。
代码案例Consumer
public class Demo01Consumer { /** 定义一个方法 方法的参数传递一个字符串的姓名 方法的参数传递Consumer接口,泛型使用String 可以使用Consumer接口消费字符串的姓名 */ public static void method(String name, Consumer<String> con){ con.accept(name); } public static void main(String[] args) { //调用method方法,传递字符串姓名,方法的另一个参数是Consumer接口,是一个函数式接口,所以可以传递Lambda表达式 method("zjq666",(String name)->{ //对传递的字符串进行消费 //消费方式:直接输出字符串 //System.out.println(name); //消费方式:把字符串进行反转输出 String reName = new StringBuffer(name).reverse().toString(); System.out.println(reName); }); } }输出如下:
666qjz如果一个方法的参数和返回值全都是Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作,然后再做一个操作,实现组合。
代码案例Consumer_andThen
public class Demo02AndThen { //定义一个方法,方法的参数传递一个字符串和两个Consumer接口,Consumer接口的泛型使用字符串 public static void method(String s, Consumer<String> con1 ,Consumer<String> con2){ //con1.accept(s); //con2.accept(s); //使用andThen方法,把两个Consumer接口连接到一起,在消费数据 con1.andThen(con2).accept(s);//con1连接con2,先执行con1消费数据,在执行con2消费数据 } public static void main(String[] args) { //调用method方法,传递一个字符串,两个Lambda表达式 method("Hello World", (t)->{ //消费方式:把字符串转换为大写输出 System.out.println(t.toUpperCase()); }, (t)->{ //消费方式:把字符串转换为小写输出 System.out.println(t.toLowerCase()); }); } }输出如下:
HELLO WORLD hello world判断型接口Predicate
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate<T> 接口。Predicate接口中包含一个抽象方法:
-
boolean test(T t):用来对指定数据类型数据进行判断的方法结果:符合条件,返回true不符合条件,返回false
代码案例Predicate
判定字符串长度是否大于5
public class Demo01Predicate { /** 定义一个方法 参数传递一个String类型的字符串 传递一个Predicate接口,泛型使用String 使用Predicate中的方法test对字符串进行判断,并把判断的结果返回 */ public static boolean checkString(String s, Predicate<String> pre){ return pre.test(s); } public static void main(String[] args) { //定义一个字符串 String s = "abcdef"; //调用checkString方法对字符串进行校验,参数传递字符串和Lambda表达式 /**boolean b = checkString(s,(String str)->{ //对参数传递的字符串进行判断,判断字符串的长度是否大于5,并把判断的结果返回 return str.length()>5; });*/ //优化Lambda表达式 boolean b = checkString(s,str->str.length()>5); System.out.println(b); } }输出如下
true代码案例Predicate_and
Predicate接口中有一个方法and,表示并且关系,也可以用于连接两个判断条件default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> this.test(t) && other.test(t);}方法内部的两个判断条件,也是使用&&运算符连接起来的
public class Demo02Predicate_and { /** 定义一个方法,方法的参数,传递一个字符串 传递两个Predicate接口 一个用于判断字符串的长度是否大于5 一个用于判断字符串中是否包含a 两个条件必须同时满足 */ public static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){ //return pre1.test(s) && pre2.test(s); return pre1.and(pre2).test(s);//等价于return pre1.test(s) && pre2.test(s); } public static void main(String[] args) { //定义一个字符串 String s = "abcdef"; //调用checkString方法,参数传递字符串和两个Lambda表达式 boolean b = checkString(s,(String str)->{ //判断字符串的长度是否大于5 return str.length()>5; },(String str)->{ //判断字符串中是否包含a return str.contains("a"); }); System.out.println(b); } }输出如下:
true代码案例Predicate_or
Predicate接口中有一个方法or,表示或者关系,也可以用于连接两个判断条件default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t);}方法内部的两个判断条件,也是使用||运算符连接起来的
public class Demo03Predicate_or { /** 定义一个方法,方法的参数,传递一个字符串 传递两个Predicate接口 一个用于判断字符串的长度是否大于5 一个用于判断字符串中是否包含a 满足一个条件即可 */ public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){ //return pre1.test(s) || pre2.test(s); return pre1.or(pre2).test(s);//等价于return pre1.test(s) || pre2.test(s); } public static void main(String[] args) { //定义一个字符串 String s = "bc"; //调用checkString方法,参数传递字符串和两个Lambda表达式 boolean b = checkString(s,(String str)->{ //判断字符串的长度是否大于5 return str.length()>5; },(String str)->{ //判断字符串中是否包含a return str.contains("a"); }); System.out.println(b); } }代码案例Predicate_negate
Predicate接口中有一个方法negate,也表示取反的意思default Predicate<T> negate() {return (t) -> !test(t);}
public class Demo04Predicate_negate { /** 定义一个方法,方法的参数,传递一个字符串 使用Predicate接口判断字符串的长度是否大于5 */ public static boolean checkString(String s, Predicate<String> pre){ //return !pre.test(s); return pre.negate().test(s);//等效于return !pre.test(s); } public static void main(String[] args) { //定义一个字符串 String s = "abc"; //调用checkString方法,参数传递字符串和Lambda表达式 boolean b = checkString(s,(String str)->{ //判断字符串的长度是否大于5,并返回结果 return str.length()>5; }); System.out.println(b); } }输出:true
类型转换接口Function
java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。Function接口中最主要的抽象方法为:R apply(T t),根据类型T的参数获取类型R的结果。使用的场景例如:将String类型转换为Integer类型。
代码案例Function
public class Demo01Function { /** 定义一个方法 方法的参数传递一个字符串类型的整数 方法的参数传递一个Function接口,泛型使用<String,Integer> 使用Function接口中的方法apply,把字符串类型的整数,转换为Integer类型的整数 */ public static void change(String s, Function<String,Integer> fun){ //Integer in = fun.apply(s); int in = fun.apply(s);//自动拆箱 Integer->int System.out.println(in); } public static void main(String[] args) { //定义一个字符串类型的整数 String s = "1234"; //调用change方法,传递字符串类型的整数,和Lambda表达式 change(s,(String str)->{ //把字符串类型的整数,转换为Integer类型的整数返回 return Integer.parseInt(str); }); //优化Lambda change(s,str->Integer.parseInt(str)); } }代码案例Function_andThen
Function接口中的默认方法andThen:用来进行组合操作
public class Demo02Function_andThen { /** 定义一个方法 参数串一个字符串类型的整数 参数再传递两个Function接口 一个泛型使用Function<String,Integer> 一个泛型使用Function<Integer,String> */ public static void change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){ String ss = fun1.andThen(fun2).apply(s); System.out.println(ss); } public static void main(String[] args) { //定义一个字符串类型的整数 String s = "123"; //调用change方法,传递字符串和两个Lambda表达式 change(s,(String str)->{ //把字符串转换为整数+10 return Integer.parseInt(str)+10; },(Integer i)->{ //把整数转换为字符串 return i+""; }); //优化Lambda表达式 change(s,str->Integer.parseInt(str)+10,i->i+""); } }本文内容到此结束了, 如有收获欢迎点赞