文章目录

  • 函数式接口
    • 概念
      • 函数式接口作为方法参数
      • 函数式接口作为方法的返回值
      • 常用函数式接口
        • 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< T > 产生一个T类型的数据
Consumer< T > 接收一个T类型的数据
Predicate< T > 判断T类型的参数是否满足指定条件,返回boolean类型
Function< T,R > 输入T类型的参数,输出R类型的参数,按照指定的操作完成
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 >有两个方法:
方法名 说明
void accept(T t) 对给定的参数执行此操作
此操作最终是在Lambda表达式中实现的
default Consumer< T > andThen(Consumer < ? super T > after)
default Consumer< T > andThen (Consumer after)
返回一个组成的Consumer,依次执行此操作,然后执行after操作
案例:
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 > 有常用的四个方法:
方法名 说明
boolean test(T t) 对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
Predicate对象.test()
default Predicate< T > negate() 返回一个逻辑的否定,对应逻辑非
Predicate对象.negate().test()
default Predicate< T > and(Predicate other) 返回一个组合判断,对应短路与
Predicate对象1.and(Predicate对象2).test()
default Predicate< T > or(Predicate other) 返回一个组合判断,对应短路或
Predicate对象1.or(Predicate对象2).test()
案例:
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>常用的两个方法:
方法名 说明
R apply(T t) 将此函数应用于给定的参数
default < V > Function andThen(Function after) 返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
案例:
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相关推荐

  1. Java23-day14【函数式接口(Supplier\Consumer\Predicate\Function)、Stream流(生产方式\中间方法\终结方法)】

    视频+资料[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java世界的大门)--博 ...

  2. Java 新特性总结

    Java 新特性总结¶ 总结的这些新特性,都是自己觉得在开发中实际用得上的. 简单概括下就是: JAVA1.3:普通的原始的JAVA,基本语法相信大家都见过了 JAVA1.4:assert关键字 JA ...

  3. 青空の霞光Java新特性笔记

    Java新特性介绍 **注意:**推荐完成此路线所有前置内容后,再来学习本篇. 经过前面的学习,我们基本已经了解了Java 8及之前的所有语法,不过,Java 8是Oracle 公司于 2014 年 ...

  4. Java新特性(二)

    这段时间太忙,更新的频率有点小了!刚解决了一个复杂的算法问题,现在就抽这点时间来讲讲剩下的一部分java新特性. 在上一节中我们学过泛型.自动装箱拆箱.for循环,这一节的内容是可变长参数.枚举类型和 ...

  5. c++11新特性的使用---可变模板参数、type_traits、function综合使用

    DLL帮助类 c++中手动调用dll是比较繁琐的,调用过程是:加载dll后还要定义一个对应的函数指针类型,接着调用GetProAddress获取函数地址,在转成函数指针,最后调用该函数如下例子: #i ...

  6. java 新特性之 stream 流

    java 新特性之 stream 流 Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据. 这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在 ...

  7. html5新特性:利用history的pushState等方法来解决使用ajax导致页面后退和前进的问题

    html5新特性:利用history的pushState等方法来解决使用ajax导致页面后退和前进的问题 参考文章: (1)html5新特性:利用history的pushState等方法来解决使用aj ...

  8. 使用 @ControllerAdvice 和 实现ResponseBodyAdvice接口, 拦截Controller方法默认返回参数,统一处理返回值/响应体

    使用 @ControllerAdvice 和 实现ResponseBodyAdvice接口, 拦截Controller方法默认返回参数,统一处理返回值/响应体 1.Controller代码 以下是Co ...

  9. java新特性对数组的支持

    2019独角兽企业重金招聘Python工程师标准>>> 在JDK1.5之后提供了两个重要的概念: 1)foreach输出 2)可变参数 1.foreach 语法格式: for(数据类 ...

最新文章

  1. 机器学习(MACHINE LEARNING) 【周志华版-”西瓜书“-笔记】 DAY3-线性模型
  2. stm32 isp下载官方软件android_OpenCanvas免费版下载_OpenCanvas绘图软件官方版下载7.0.25...
  3. Spring MVC 流程图解析
  4. 【飞控理论】四旋翼飞行器控制原理
  5. php更改tittle,phpcms V9修改默认title标签
  6. 使用 Python 第三方库 daft 绘制 PGM 中的贝叶斯网络
  7. 使用google analytics(分析)监测百度竞价关键词效果(网址构建工具)
  8. 公共邮箱,共享邮箱,免费邮箱,匿名邮箱,临时邮箱,免费收信
  9. Jeff Dean:谷歌大脑背后的“大脑” | AI名人堂
  10. 【渝粤教育】电大中专跨境电子商务理论与实务 (31)作业 题库
  11. ceph rbd mysql_怎样配置ceph rbd存储类型?
  12. 关于java中method.invoked 传入类型不一样的问题
  13. 22考研初试410数一145上岸上海交通大学819经验分享
  14. android集成Crosswalk内核,屏蔽返回键问题。
  15. spring常见面试题(2023最新)
  16. c/c++ read 函数和 write 函数
  17. 3A和ISP算法概念梳理
  18. WebMatrix使用例子
  19. 硬件电路板调试方法及步骤
  20. antdpro 中 使用 antd select 组件,defaultValue 与 value 使用问题

热门文章

  1. 作文 深海机器人_作文机器人(共5篇)
  2. 约瑟夫环(51nod)
  3. InnoDB: Running in read-only mode 问题排查
  4. API Gateway(API网关)介绍
  5. 英雄之刃显示服务器断开怎么办,英魂之刃手游新手常见问题
  6. 力挺京东618,马化腾用小程序给刘强东送了一份大礼!
  7. ICDAR2017中文检测数据集
  8. go-redis 使用
  9. 计算机在石油工程中应用文献综述,石油与天然气工程领域工程硕士专业学位基本要求第一部分概况.PDF...
  10. java 数字和字母_java-如何在字母和数字之间(或数字和字母之间)分割字符串?...