1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java新特性-函数式接口-作为方法参数-作为方法的返回值-常用函数式接口-Supplier-Cons

java新特性-函数式接口-作为方法参数-作为方法的返回值-常用函数式接口-Supplier-Cons

时间:2022-08-27 15:27:51

相关推荐

java新特性-函数式接口-作为方法参数-作为方法的返回值-常用函数式接口-Supplier-Cons

文章目录

函数式接口概念函数式接口作为方法参数函数式接口作为方法的返回值常用函数式接口Supplier接口常用函数式接口 Consumer函数式接口之 Predicate接口常用接口之Function 接口

函数式接口

概念

函数式接口 = 有且仅有一个抽象方法的接口;java中的函数式编程体现的就是Lambda表达式 = 函数式接口可以适用于Lambda使用的接口;java的Lambda表达式使用的前提 = 保证接口中有且仅有一个抽象方法。

小知识点:

子类重写父类方法,会有注解@Override。函数式接口 的注解是 @FunctionalInterface,检测是不是函数式接口。

案例:

public class MyInterfaceDemo {public static void main(String[] args) {// 函数式接口可以用作方法的参数传递// 是不是说Lambda表达式啊useShow(()-> System.out.println("方法的参数传递"));// 函数式接口用作局部变量MyInterface my = () -> System.out.println("局部变量");// 将Lambda表达式 赋值给 函数式接口// 上述等价于/*MyInterface my = new MyInterface() {@Overridepublic void show() {System.out.println("局部变量");}};*/my.show();}private static void useShow(MyInterface mif){mif.show();}}

函数式接口作为方法参数

如果方法的参数是一个函数式接口,可以使用Lambda表达式作为参数传递。

startThread(() -> System.out.println(Thread.currentThread().getName() + ""));

需求:

类(RunnableDemo),两个方法:startThread(Runnable r)方法参数Runnable是一个函数式接口;

main主方法,调用startThread方法

public class RunnableDemo {public static void main(String[] args) {// 调用startThread方法// 匿名内部类的方式startThread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "线程启动了");}});// Lambda表达式 的方式startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));}private static void startThread(Runnable r){/* Thread t = new Thread(r);t.start();*/// 简写new Thread(r).start();// 也就是线程的启动}}

函数式接口作为方法的返回值

如果方法的返回值是一个函数式接口,使用Lambda表达式作为结果返回。

匿名内部类:private static Comparator<String> getComparator(){return (s1,s2) -> s1.length()-s2.length();}

需求:

类(ComparatorDemo),两个方法:

Comparator< String >getComparator() 方法返回值Comparator是一个函数式接口

主方法main,调用getComparator方法

public class ComparatorDemo {/*类(ComparatorDemo),两个方法:Comparator< String >getComparator() 方法返回值Comparator是一个函数式接口主方法main,调用getComparator方法*/public static void main(String[] args) {// 创建集合,存储字符串字符ArrayList<String> array = new ArrayList<String>();array.add("cccc");array.add("aa");array.add("b");array.add("ddd");System.out.println("排序前:" + array);// 输出内容是:排序前:[cccc, aa, b, ddd]// 就是按照集合添加的顺序。// 自然排序 按照自然排序。Collections.sort(array);System.out.println("排序后:" + array);// 输出内容:排序后:[aa, b, cccc, ddd]//Collections.sort(array, getComparator());System.out.println("排序后1:" + array);}private static Comparator<String> getComparator(){// 返回值是Comparator的实现类对象// 使用匿名内部类的形式/*Comparator<String> c = new Comparator<String>(){@Overridepublic int compare(String s1, String s2) {return s1.length() - s2.length();}};return c;*/// 改进 省略 这里使用的是匿名内部类的方式。// return new Comparator<String>() {// @Override// public int compare(String s1, String s2) {//return s1.length() - s2.length();//// 正数 s1待比较数据 s2是已存在的数据//// 也就是 长的数据放在后面// }// };// 改进 使用Lambda表达式// return (String s1,String s2) -> {// return s1.length() - s2.length();// };// 省略形式return (s1,s2) -> s1.length()-s2.length();}}

常用函数式接口

java 8 在java.util.function包下预定了大量的函数式接口供使用

四个接口:Supplier接口、Consumer接口、Predicate接口、Function接口。

Supplier接口

概述:

在java.util.function包下,使用需要导包代表接口供应商,主要用来生产数据Supplier< T > :包含一个无参的方法,T表示泛型T get() : 获取结果,该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据Supplier< T > 接口被称为生产型接口,制定了接口的泛型是什么类型,接口中的get方法就会产生什么类型的数据

案例:

public class SupplierDemo {public static void main(String[] args) {// getString 方法的参数是函数式接口,那么实际上传递的是接口的实现类对象。// 只有一个方法get,// 匿名内部类形式String st = getString(new Supplier<String>() {@Overridepublic String get() {return "you";}});System.out.println(st);// Lambda表达式形式String s = getString(()->{return "sunshine";});System.out.println(s);// 省略String name = getString(() -> "汪苏泷");System.out.println(name);Integer i = getInteger(() -> 30);}// 定义方法,返回一个字符串private static String getString(Supplier<String> sup){return sup.get();}// 定义方法,返回一个整数private static Integer getInteger(Supplier<Integer> sup){return sup.get();}}

练习:

需求:

类(SupplierTest),两个方法:int getMax(Supplier< Integer > sup)用于返回一个int数组中的最大值;

main方法 调用getMax方法。

public class SupplierTest {public static void main(String[] args) {/*类(SupplierTest),两个方法:int getMax(Supplier< Integer > sup)用于返回一个int数组中的最大值;main方法 调用getMax方法。*/int[] array = {19,50,28,27,46};int MaxValue = getMax(() -> {int max = array[0];for(int i = 1; i < array.length ; i++){if(array[i] > max){max = array[i];}}return max;});System.out.println(MaxValue);}private static Integer getMax(Supplier<Integer> sup){return sup.get();// 具体的操作 还得Lambda表达式 进行设置}}

常用函数式接口 Consumer

概念:

在java.util.function包下,使用需要导包是一个消费型的接口,消费的类型由泛型指定,接收单个输入参数并且不返回结果Consumer< T >有两个方法:

public class ConsumerDemo {public static void main(String[] args) {// 调用operatorString方法operatorString("汪苏泷", (String s)->{System.out.println(s);});// 省略operatorString("许嵩", s -> System.out.println(s));// 方法引用的形式 引用类的方法 类::静态方法operatorString("林俊杰", System.out::println);// 将输出内容翻转operatorString("周杰伦", s -> {System.out.println(new StringBuilder(s).reverse().toString());});System.out.println("------------------");operatorString1("胡夏", s-> System.out.println(s), s-> System.out.println(new StringBuffer(s).reverse().toString()));}// 定义方法,消费一个字符串private static void operatorString(String name, Consumer<String> con){con.accept(name);// 具体的操作由Lambda表达式书写}// 定义方法 ,用不同的方式消费同一个字符串数据两次// 也就是有两个Consumer接口private static void operatorString1(String name,Consumer<String> con1,Consumer<String> con2){// con1.accept(name);// con2.accept(name);// 使用andThen改进con1.andThen(con2).accept(name);/* default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };}*/}}

练习:

要求:

String[] strArray = {“汪苏泷,30”,“许嵩,32”,“胡夏,32”};

字符串数组中有多条信息,请按照格式:“姓名:xx,年龄:xx”的格式输出打印

把打印姓名的动作 第一个 Consumer 接口的Lambda实例

把打印年龄的动作 第二个 Consumer 接口的Lambda实例

将两个Consumer接口按照顺序组合到一起使用

public class ConsumerTest {/*字符串数组中有多条信息,请按照格式:“姓名:xx,年龄:xx”的格式输出打印把打印姓名的动作 第一个 Consumer 接口的Lambda实例把打印年龄的动作 第二个 Consumer 接口的Lambda实例将两个Consumer接口按照顺序组合到一起使用*/public static void main(String[] args) {String[] strArray = {"汪苏泷,30","许嵩,32","胡夏,32"};// 自己的for(String str:strArray){printNameAge(str, s -> {String name = s.split(",")[0];System.out.print("姓名:" + name);},s->{String age = s.split(",")[1];System.out.println(",年龄:" + age);});}System.out.println("---------------");// 视频中的printInfo(strArray, s->{String name = s.split(",")[0];System.out.print("姓名:" + name);}, s->{String age = s.split(",")[1];System.out.println(",年龄:" + age);});}// 自己的想法private static void printNameAge(String str, Consumer<String> con1,Consumer<String> con2){con1.andThen(con2).accept(str);}// 视频中想法private static void printInfo(String[] strArray,Consumer<String> con1,Consumer<String>con2){for(String str:strArray){con1.andThen(con2).accept(str);}}}

函数式接口之 Predicate接口

概念:

在java.util.funciton包下,使用需要导包Predicate接口 表示参数的谓词(布尔值函数),对参数进行判断,返回一个布尔值。Predicate< T > 接口通常用于判断参数是否满足指定的条件Predicate< T > 有常用的四个方法:

public class PredicateDemo {public static void main(String[] args) {// 调用checkString方法boolean b = checkString("sun",(String str)->{return str.length() > 5;});System.out.println(b);boolean b1 = checkString("sunshine", str -> str.length() > 5);System.out.println(b1);}// 判断给定的字符串是否满足要求private static boolean checkString(String s, Predicate<String> pre){// return pre.test(s);// 具体的实现在 调用它的Lambda表达式中实现// 想实现逻辑非的操作// return !pre.test(s);// 不是使用上述形式,而是采用negate方法,且negate方法得在test方法之前return pre.negate().test(s);}}

案例:

public class PredicateDemo2 {public static void main(String[] args) {boolean b1 = checkString("sun", s->s.length()>2);System.out.println(b1);boolean b2 = checkString("sunshine", s->s.length()<5);System.out.println(b2);System.out.println("--------------");boolean b3 = checkStringAdd("hello", s->s.length()>6, s1 -> s1.length() <15);System.out.println(b3);}// 同一个字符串做两个不同的判断,并将两个判断结果做逻辑与的结果作为最终输出结果private static boolean checkStringAdd(String s ,Predicate<String> pre1,Predicate<String> pre2){// boolean b1 = pre1.test(s);// boolean b2 = pre2.test(s);// boolean b = b1 && b2;// return b;// 实现短路与 可以使用方法and// return pre1.and(pre2).test(s);/*default Predicate<T> and(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) && other.test(t);}*/// 实现短路或 可以使用方法orreturn pre1.or(pre2).test(s);/*default Predicate<T> or(Predicate<? super T> other) {Objects.requireNonNull(other);return (t) -> test(t) || other.test(t);}*/}// 判断给定字符串是否满足条件private static boolean checkString(String s, Predicate<String> pre){return pre.test(s);}}

练习:

需求:

String[] strArray = {“汪苏泷,30”,“许嵩,34”,“林俊杰,35”,“胡夏,31”,“周杰伦,33”};

字符串数组中有多条信息,请通过Predicate接口的拼接将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合

同时满足要求:姓名长度大于2;年龄大于33;

public class PredicateDemo3 {public static void main(String[] args) {String[] strArray = {"汪苏泷,30","许嵩,34","林俊杰,35","胡夏,31","周杰伦,33"};// 自己写的方法:方法1// ArrayList<String> array = new ArrayList<String>();// for(String s:strArray){// boolean b = checkName(s, (String s1) -> {//String name = s1.split(",")[0];//return name.length()>2;// }, (String s2)->{//int age = Integer.parseInt(s2.split(",")[1]);//return age>33;// });// if(b){//array.add(s);// }// }// for(String s:array){// System.out.println(s);// }// 方法2 ArrayList<String> arr = checkName2(strArray,(String s)->{String name = s.split(",")[0];return name.length() >2;},(String s2)->{int age = Integer.parseInt(s2.split(",")[1]);return age>33;});for(String s:arr){System.out.println(s);}}// 自己写的 方法1private static boolean checkName(String str, Predicate<String> pre1, Predicate<String> pre2){return pre1.and(pre2).test(str);}// 通过Predicate接口的拼接将符合要求的字符串筛选到集合ArrayList中,并遍历ArrayList集合 方法2private static ArrayList<String>checkName2(String[] strs,Predicate<String> pre1,Predicate<String> pre2){// 定义集合ArrayList<String> arr = new ArrayList<String>();// 遍历String数组for(String s:strs){if(pre1.and(pre2).test(s)){arr.add(s);}}return arr;}}

常用接口之Function 接口

概念:

在java.util.function包下,使用需要导包Interface Function< T , R > T 是函数输入的类型,R 是函数输出的类型,表示接收一个参数 并产生结果 的函数Function< T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值Function< T,R>常用的两个方法:

public class FunctionDemo {public static void main(String[] args) {// 方法1convertInt("1024", (String s)->{return Integer.parseInt(s);});// 优化convertInt("2048",s -> Integer.parseInt(s));// 方法2convertString(924, (Integer i)->{return String.valueOf(i+100);});// 方法3 自己的convertStrToIntToString("1022", s->{return String.valueOf(Integer.parseInt(s) + 1000);});// 方法3 视频中的convertStrToIntToString("1000", s->Integer.parseInt(s)+24,i->String.valueOf(i));}// 定义一个方法,把一个字符串转换为int类型,在控制台输出 方法1private static void convertInt(String s, Function<String,Integer> fun){Integer i = fun.apply(s);System.out.println(i);}// 方法2 把一个int类型的数 加上一个整数之后,转为字符串在控制台输出private static void convertString(Integer i,Function<Integer,String> fun){String s = fun.apply(i);System.out.println(s);}// 方法3 把一个字符串转为int类型,加上一个整数之后,转为字符串在控制台输出 自己的private static void convertStrToIntToString(String st,Function<String,String> fun){String str = fun.apply(st);System.out.println(str);}// 方法3 把一个字符串转为int类型,加上一个整数之后,转为字符串在控制台输出 自己的private static void convertStrToIntToString(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){// Integer i = fun1.apply(s);// String ss = fun2.apply(i);// System.out.println(ss);// 使用andThen方法改进String ss = fun1.andThen(fun2).apply(s);System.out.println(ss);/* default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}*/}}

练习:

需求:

String s = “汪苏泷,30”;

操作:①字符串截取得到数字年龄部分;②将数字年龄字符串转为int类型的数据;③数据加70,在控制台输出

public class FunctionDemo2 {public static void main(String[] args) {String s = "汪苏泷,30";// xhjsumAge(s, s1 -> {String age = s.split(",")[1];return Integer.parseInt(age ) + 70;});// videoconvert(s, s1 -> s.split(",")[1],s2 -> Integer.parseInt(s2), i -> i + 70);}// xhjprivate static void sumAge(String s, Function<String,Integer> fun1){Integer i = fun1.apply(s);System.out.println(i);}// videoprivate static void convert(String s,Function<String,String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){Integer i = fun1.andThen(fun2).andThen(fun3).apply(s);System.out.println(i);}}

java新特性-函数式接口-作为方法参数-作为方法的返回值-常用函数式接口-Supplier-Consumer-Predicate-Function

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。