函数式接口

1、 函数式接口概念及基本使用

1、函数式接口:有且仅有一个抽象方法的接口,函数式接口就是Lambda表达式使用的前提

2、 Java中的函数式编程体现的就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口,

只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导

注:@FunctionalInterface 在接口上加上这个注解就表达该接口是函数式接口

public class MyInterfaceDemo {
   public static void main(String[] args) {
       //函数式接口做为局部变量时,可以把Lambda表达式赋值给它
       MyInterFace my = ()-> System.out.println("函数式接口");
       my.show();
   }
}

//加上这个注解,就表示它是函数式接口,在到里面添加一个抽象方法,注解就会报错
@FunctionalInterface
public interface MyInterFace {
   void show();
}

2、函数式接口做为方法参数 

需求:

1. 定义一个类(RunnableDemo),在类中提供两个方法

2. 一个方法是:startThread(Runnable  r),方法参数Runnable是一个函数式接口

3. 一个方法是主方法,在主方法中调用startThread方法

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

例如:StartThread(() -> System.out.println(Thread.currentThread().getName()+”线程启动了”))

public class RunnableDemo {
   public static void main(String[] args) {
       //第一种:匿名内部类的方式
       startThread(new Runnable() {
           @Override
           public void run() {
               System.out.println(Thread.currentThread().getName()+"线程启动了!");
           }
       });
       //第二种:Lambda表达式
       startThread(()->{
           System.out.println(Thread.currentThread().getName()+"线程启动了!");
       });
   }
   //Runnable为函数式接口,Ctrl+B可以查看源码
   public static void startThread(Runnable  r){
       new Thread(r).start();//开启一个线程
   }
}

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

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

例如:private static Comparator<String> getComparator(){

Return(s1,s2) -> s1.length() - s2.length();

}

/*需求:
1.定义一个类ComparatorDemo,在类中提供两个方法
2.一个方法是:Comparator<String>  getComparator()方法返回值Comparator是一个函数式接口
3.一个方法是主方法,在主方法中调用getComparator()方法
* */
public class ComparatorDemo {
   public static void main(String[] args) {
       //构造使用场景
       //定义集合,存储字符串元素
       ArrayList<String> arr = new ArrayList<String>();
       arr.add("aaaaa");
       arr.add("ccc");
       arr.add("bbbbbb");
       arr.add("ddd");
       System.out.println("排序前"+arr);
       //Collections.sort(arr);//r如果只是传递arr这个集合参数,就是按照自然顺序进行排序
       //System.out.println("排序后"+arr);

//使用Comparator<String>比较器排序
       Collections.sort(arr,getComparator());//按照字母顺序,及字符长度进行排序
       System.out.println("排序后"+arr);
   }
   //Comparator<String>比较器排序类的接口,返回的是该接口的实现类对象
   private static Comparator<String> getComparator(){
       //第一种:匿名内部类的方式(原始方式)
       /*Comparator<String> comp = new Comparator<String>() {
           @Override
           public int compare(String s1, String s2) {
               return s1.length()-s2.length();
           }
       };*/
       //第一种:匿名内部类的方式(改进方式)
       /*return new Comparator<String>() {
           @Override
           public int compare(String s1, String s2) {
               return s1.length()-s2.length();
           }
       };*/
       //第二种:Lambda表达式
       return(String s1,String s2)->{
          return s1.length()-s2.length();
       };
   }
}

4、 常用的函数式接口(Supplier接口)

Java8在java.util.function包下预定义了大量的函数式接口提供给我们使用

重点学习下面4个接口:Supplier接口、Consumer接口、Predicate接口、Function接口

Supplier<T>包含一个无参的方法:

1、T get() :获得结果

2、该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据

3、Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用

//Supplier接口基本使用

public class SupplierDemo {
   public static void main(String[] args) {
       //Lambda表达式方式,获取一个字符串数据
       String s = getString(()->{
           return "中国北京";
       });
       System.out.println(s);
       //Lambda表达式方式,获取一个整数数据
       Integer i = getInter(()->{
           return 30;
       });
       System.out.println(i);
   }
   //定义一个方法,返回一个字符串数据
   private static String getString(Supplier<String> sup){
       return sup.get();
   }
   //定义一个方法,返回一个整数数据
   private static Integer getInter(Supplier<Integer> sup){
       return sup.get();
   }
}

5、Supplier小练习

/*练习:
1、定义一个类SupplierTest,在类中提供两个方法
2、一个方法是:int getMax(Supplier<Integer> sup),用于返回一个int数组中的最大值
3、一个方法是主方法,在主方法中调用getMax方法
* */
public class SupplierTest {
   public static void main(String[] args) {
       //定义一个数组
       int[] arr = {12,23,21,34,54,65};

//Lambda表达式的方式,返回值是一个int类型
       int maxValue = getMax(()->{
           int max =0;
           for(int x=1;x<arr.length;x++){
               if(arr[x] > max){
                   max = arr[x];
               }
           }
           return max;
       });
       System.out.println(maxValue);
   }
   //用于返回一个int数组中的最大值
   private static int getMax(Supplier<Integer> sup){
       return sup.get();
   }
}

6、常用的函数式接口(Consumer接口)

//Consumer接口基本操作
public class ConsumerDemo {
   public static void main(String[] args) {
       //第一种:Lambda表达式
       operatorString("中国北京",(String s)->{
           System.out.println(s);
       });
       /*第二种:方法引用
       operatorString("中国北京",System.out::println);*/

//第三种方式:对字符串反转后再转成字符串进行输出
       operatorString("中国北京",(String s)->{
           System.out.println(new StringBuilder(s).reverse().toString());
       });
       System.out.println("------------------------");
       //调用2次消费的方法
       operatorString("中国北京",(String s)->
           System.out.println(s),(String s) ->System.out.println(new StringBuilder(s).reverse().toString())
       );
   }
   //定义一个方法,消费一个字符串数据
   private static void operatorString(String name, Consumer<String> con){
       con.accept(name);
   }
   //定义一个方法,用不同的方式消费一个字符串数据两次
   private static void operatorString(String name, Consumer<String> con1,Consumer<String> con2){
       /*con1.accept(name);
       con2.accept(name);*/
       //对上面两句改进优化
       con1.andThen(con2).accept(name);
   }
}

7、Consumer接口小练习

//Consumer小练习
public class ConsumerDemo2 {
   public static void main(String[] args) {
       String[] strArray = {"浙江杭州,20","江苏南京,30","广东深圳,40"};
       pringtInfo(strArray,(String str)->{
           String name  = str.split(",")[0];
           System.out.print("姓名"+name);
       },(String str)->{
           int age = Integer.parseInt(str.split(",")[1]);
           System.out.println(",年龄"+age);
               } );
   }
   private static void pringtInfo(String[] strArray, Consumer<String> con1,Consumer<String> con2){
       for(String str: strArray){
           con1.andThen(con2).accept(str);
       }
   }
}

8、常用的函数式接口(Predicate接口)

//Predicate接口test、negate方法
public class PrediccateDemo1 {
   public static void main(String[] args) {
       //判断hello这个字符串的长度是否大于8
       boolean b1 = checkString("hello",(String s)->{
           return s.length()>8;
       });
       System.out.println(b1);
   }
   //判断给定的字符串是否满足要求
   private static boolean checkString(String s, Predicate<String> pre){
       //return pre.test(s);
       return pre.negate().test(s); //对结果取反
   }
}

//Predicate接口的add、or方法
public class PredicateDemo2 {
   public static void main(String[] args) {
       boolean b3 = checkString("hello",(String s)->s.length()>8,s -> s.length()<15);
       System.out.println(b3);
   }
   //同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
   private static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){
       /*boolean b1 = pre1.test(s);
       boolean b2 = pre2.test(s);
       boolean b = b1 && b2;
       return b;*/

//add方法对上面的代码进行优化
       //return pre1.and(pre2).test(s);

//or方法
       return pre1.or(pre2).test(s);
   }
}

9、Predicate接口小练习

//Predicate小练习
public class PredicateDemo3 {
   public static void main(String[] args) {
       String[] arrString = {"浙江杭州,30","西安,31","深圳,33","四川成都,34"};
       ArrayList<String> array = myFilter(arrString,s->s.split(",")[0].length()>2,
               s->Integer.parseInt(s.split(",")[1])>33);
       for(String str: array){
           System.out.println(str);
       }
   }
   //通过Predicate接口拼装,将符合要求的字符串筛选到集合中
private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2){
       //定义一个集合
   ArrayList<String> array = new ArrayList<String>();
   //遍历数组
   for(String str:strArray){
       if(pre1.and(pre2).test(str)){
           array.add(str);
       }
   }
   return array;
   }
}

10、常用的函数式接口(Function接口)

//Function接口的2个方法的基本使用
public class FunctionDemo {
   public static void main(String[] args) {
       //第一种:Lambda表达式调用第一个方法
       convery("100",(String s)->{
           return Integer.parseInt(s);
       });
       //第二种:方法引用调用第一个方法
       convery("100",Integer::parseInt);
       //Lambda表达式调用第二个方法
       convery1(100,(Integer i)->{
           return String.valueOf(i+500);
       });
       //Lambda表达式调用第三个方法
       convery2("100",(String s)->{
           return Integer.parseInt(s);
       },(Integer i)->{
           return String.valueOf(i+500);
       });
   }
   //定义一个方法,把字符串转换为int类型,在控制台输出
   private static void convery(String s, Function<String,Integer> fun){
       //Integer i = fun.apply(s);
       int i = fun.apply(s); //Integer和int类型接收都可以
       System.out.println(i);
   }
   //把一个int类型的数据加上一个整数过后,转换为字符串在控制台输出
   private static void convery1(Integer i,Function<Integer,String> fun){
       String s = fun.apply(i);
       System.out.println(s);
   }
   //把一个字符串转换为int类型,把int类型加上一个整数过后,转换为字符串在控制台输出
   private static void convery2(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
       /*Integer i = fun1.apply(s);
       String ss = fun2.apply(i);
       System.out.println(ss);*/
       //对上面代码进行优化
      String ss = fun1.andThen(fun2).apply(s);
       System.out.println(ss);
   }
}

11、Function接口小练习

//Function接口小练习
public class FunctionDemo1 {
   public static void main(String[] args) {
       String s = "中国北京,30";
       /*convert(s,(String ss)->{
          return s.split(",")[1];
       },(String ss)->{
         return Integer.parseInt(ss);
       },(Integer i)->{
           return i+70;
       });*/
       //对上面代码进行优化
       convert(s,ss->s.split(",")[1],ss->Integer.parseInt(ss),i->i+70);
   }
private 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. 【Java 进阶】匿名类(代码传递、回调、过滤器)、Lambda表达式(方法引用)、函数式接口(Supplier、Consumer、Predicate、Function)

    匿名类 匿名类(Anonymous Class) 匿名类的使用注意 匿名类 - 代码传递 - 测试代码运行时间的工具类 匿名类 - 回调 - 简易网络请求 匿名类 - 过滤器 - 获取目录下的所有文件 ...

  2. Java基础(十二)

    合成设计模式的引出 引用传递实际应用 案例一(类关联结构) 有的人有一辆汽车,有些人坐公交:要求通过面向对象的设计来解决实现以上的这种关系转换. class Car{private String na ...

  3. Java基础语法十二 泛型程序设计

    1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...

  4. 重学java基础第二十二课:IDEA安装

  5. 重学java基础第十二课:计算机语言发展史

  6. 二十六、设置时序电路初始状态的方法(初始值设置)(时序电路置数)

    ---------------------------------------------------------------------------------------------------- ...

  7. 阶段1 语言基础+高级_1-2 -面向对象和封装_11使用对象类型作为方法的返回值

    自定义的类做为方法的返回值.新建类Dmeo05 谁调用我,我就把one的地址返回给谁 内存中发生了什么 程序要想运行main方法先进栈 进来以后定义了一个phone two.two和刚才有什么不一样? ...

  8. Java基础知识(二)(Object类的常用方法、日期时间类、System类、StringBuilder类、包装类、Collection集合、Iterator迭代器、泛型、list集Set接口...)

    文章目录 Java基础知识(二) 1.Object类的常用方法 1.1 toString方法 1.2 equals方法 1.3 Objects类 2.日期时间类 2.1 Date类 2.2 DateF ...

  9. JAVA基础知识总结:一到二十二全部总结

    >一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...

最新文章

  1. 【springboot基础】配置日志输出级别以及输出位置
  2. Tomcat的安装及配置。
  3. 1024程序员:算法仓鼠创业
  4. 腾讯想拿到Big Data资源,8h删抓紧时间!!
  5. Android的启动方式
  6. Windows系统字体和系统应用字体
  7. 游戏开发中的那点英语
  8. HYSPLIT简明教程
  9. 数据结构与算法面试题80道
  10. unity 更换standard shader
  11. 生活小常识,哪些药物不能混合用?
  12. 财源滚滚的第三方支付牌照
  13. 影视动画专业有木有c语言,那些头秃的专业,不了解一下?
  14. 微信会员卡自定义code模式--从创建到激活
  15. endnote使用方法大全,endnote教程
  16. 计算机工程学院团总支学生会,凝聚团队力量,展现青春活力——计算机工程学院团总支学生会开展学生干部素质拓展活动...
  17. c语言中int和void,关于指针:void(*)void和int(*)int在C中的含义是什么?
  18. 如何压缩图片jpg大小?怎么缩小jpg大小kb?
  19. 协议 驱动 接口 服务器,TCP/IP 协议底层驱动原理 (含网卡芯片读写) 说明 [撸 swoole 和 workerman 的同学建议瞧瞧]...
  20. 编程萌新必看!初学C语言必会的知识点,你学废了吗?

热门文章

  1. 情商的关键在于共情的能力
  2. 华为OD在线编程题准备
  3. 天融信VPN断电后web不能访问解决
  4. Ajax技术的先进性与局限性
  5. gma 教程 | 栅格处理 | 栅格镶嵌
  6. 物流相关数据分析项目两则
  7. plt.savefig()保存到本地的图片上下左右会有白边
  8. 2.1_2 Oracle 批量插入(insert all into)
  9. 高德地图联合合作伙伴,为用户十一送大礼
  10. 技术没有捷径,敢不敢坚持学习一百天