Java基础二十二:函数式接口介绍,函数式接口作为方法参数、返回值,Supplier接口、Consumer接口、Predicate接口、Function接口基本介绍及其案例小练习

函数式接口

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接口)

3e62ae1d58f54ad685ceb460ec6a4767.png 

//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接口小练习

7b98ea1ccf204f5d8bf44f8fe4b75748.png 

//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接口)

d4827d5b6b2046b8bc60a24b9647ed72.png 

//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接口小练习

587081dbf6ea4faf936ea24fecc29101.png 

//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接口)

b96b456cc0044a388a76d2a4259e95bf.png 

//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接口小练习

1c14b797466848bbbf1c03d344a67902.png 

//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);
   }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜀州凯哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值