前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数式接口

函数式接口

作者头像
秋落雨微凉
发布2022-10-25 18:03:09
2720
发布2022-10-25 18:03:09
举报

函数式接口

函数式接口:有且仅有一个抽象方法的接口

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

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

如何检验接口是否是函数式接口:

  • @FunctionalIneterface
  • 放于接口的上方:如果接口是函数式接口,编译通过;如果不是,编译失败

下面给出示例代码:

代码语言:javascript
复制
public class MyInterfaceDemo {
    public static void main(String[] args) {
        //我们采用lambda方法来创建接口对象
        MyInterface my = () -> {
            System.out.println("函数式接口");
        };
        //直接调用方法,方法是由lambda标注的
        my.show();
    }
}
代码语言:javascript
复制
//函数式接口标记
@FunctionalInterface
public interface MyInterface {
    void show();
}

函数式接口作为方法的参数

需求:

  • 定义一个类(RunnableDemo),在类中提供两个方法
    • startThread(Runnable r):方法参数是Runnable函数式接口
    • main():调用startThread方法

下面给出代码示例:

代码语言:javascript
复制
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() + ":" + "启动了");});
    }

    //定义方法
    public static void startThread(Runnable r)
    {
        new Thread(r).start();
    }
}

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

需求:

  • 定义一个类(ComparatorDemo),在类中提供两个方法
    • Comparator getComparator():方法返回值是一个Comparator,用作比较方法
    • main():调用 getComparator方法

下面给出代码示例:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;

public class ComparatorDemo {
    public static void main(String[] args) {
        //构造使用场景
        ArrayList<String> arrayList = new ArrayList<>();

        //先添加一些元素
        arrayList.add("aa");
        arrayList.add("ccc");
        arrayList.add("bbbb");
        arrayList.add("d");

        //我们输出查看结果:
        System.out.println(arrayList);

        //首先我们使用默认排序方法
        Collections.sort(arrayList);

        //我们输出查看结果:
        System.out.println(arrayList);

        //我们使用带Comparator的排序方法
        //这里我们通过GetComparator获得Comparator
        Collections.sort(arrayList,getComparator2());

        //我们输出查看结果:
        System.out.println(arrayList);
    }

    public static Comparator<String> getComparator1() {
        //这里我们通过构造器方法创建
        return new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };
    }

    public static Comparator<String> getComparator2() {
        //这里我们通过lambda方法来创建
        return (s1, s2) -> s1.length() - s2.length();
    }
}

函数式常用接口

下面我们介绍四种函数式常用接口:

  • Supplier接口:用于获得数据结果
  • Consumer接口:用于消费所加载的数据
  • Predicate接口:用于判断所加载的数据
  • Function接口:用于进行数据类型转换

Supplier接口

Supplier:包含一个无参的方法

  • T get():获得结果
  • 该方法不需要参数,会按照实现逻辑(Lambda表达式实现)返回一个数据
  • Supplier接口被称为生产型接口,如果我们指定了接口的泛型是什么类型,get方法就会产生什么类型

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Supplier;

public class Demo {
    public static void main(String[] args) {
        //我们输出由方法获得的值
        //这里是使用lambda作为参数
        System.out.println(getString(() -> "胡桃"));
        System.out.println(getInteger(() -> 30));
    }

    //GetString
    public static String getString(Supplier<String> sup){
        return sup.get();
    }

    //GetInteger
    public static Integer getInteger(Supplier<Integer> sup){
        return sup.get();
    }
}

练习:

  • 定义一个类(SupplierTest),在类中提供两个方法
    • int getMax():返回数组中最大的值
    • main():调用 getMax方法

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Supplier;

public class Demo1 {
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {2,13,44,76,52};

        //获得最大值
        int max = getMax(() -> {
            int maxValue = arr[0];
            for(int i=0;i< arr.length;i++){
                if(arr[i] > maxValue){
                    maxValue = arr[i];
                }
            }
            return maxValue;
        });
        System.out.println(max);
    }

    private static int getMax(Supplier<Integer> sup){
        return sup.get();
    }
}

Consumer接口

Consumer:包含两个方法

  • void accept(T t):对给定的参数执行此操作
  • default Consumer andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作
  • Consumer接口也被称为消费型接口,它消费的数据类型由泛型指定

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Consumer;

public class Demo1 {
    public static void main(String[] args) {
        //Consumer消费一个字符串
        operatorString1("胡桃",(String name) -> {
            System.out.println(name);
        });

        //Consumer不同方法消费同一个字符串
        operatorString2("胡桃",(String name)-> System.out.println(name),(String name) -> System.out.println(new StringBuilder(name).reverse().toString()));
    }

    //Consumer消费一个字符串
    public static void operatorString1(String name, Consumer<String> con){
        con.accept(name);
    }

    //Consumer不同方法消费同一个字符串
    public static void operatorString2(String name, Consumer<String> con1,Consumer<String> con2){
        con1.andThen(con2).accept(name);
    }
}

练习:

  • 创造一个String数组,数组以“姓名,年龄”来组成
  • 我们用Consumer接口来分别获取姓名和年龄,并输出

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Consumer;

public class Demo2 {
    public static void main(String[] args) {
        //创建一个数组
        String[] strArray = {"胡桃,18","钟离,20","七七,12"};

        //针对str做出输出
        printInfo(strArray,(String str) -> System.out.print(str.split(",")[0])
                ,(String str) -> System.out.println(Integer.parseInt(str.split(",")[1])));
    }

    //创造消费方法
    private static void printInfo(String[] strArray, Consumer<String> con1,Consumer<String> con2){
        for(String str : strArray){
            con1.andThen(con2).accept(str);
        }
    }
}

Predicate接口

Predicate:常用四个方法

  • boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
  • dafault predicate negate():返回一个逻辑的否定,对应逻辑非
  • dafault predicate and():返回一个组合判断,对应短路与
  • dafault predicate or()返回一个组合判断,对应短路或
  • Predicate接口常用于判断参数是否满足指定条件

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Predicate;

public class Demo1 {
    public static void main(String[] args) {
        System.out.println(test("Jerry",(String s) -> s.length()>8));

        System.out.println(negateTest("Jerry",(String s) -> s.length()>8));

        System.out.println(andTest("Jerry",(String s) -> s.length()<8,(String s) -> s.length()>3));

        System.out.println(orTest("Jerry",(String s) -> s.length()>10,(String s) -> s.length()<3));
    }

    public static boolean test(String s, Predicate<String> pre){
        //对s进行测试,测试内容在main中用lambda完成
        return pre.test(s);
    }

    public static boolean negateTest(String s,Predicate<String> pre){
        //对s进行反向测试,得到的结果是相反结果
        return pre.negate().test(s);
    }

    public static boolean andTest(String s,Predicate<String> pre1,Predicate<String> pre2){
        //对s进行测试,测试是否同时满足两个条件
        return pre1.and(pre2).test(s);
    }

    public static boolean orTest(String s,Predicate<String> pre1,Predicate<String> pre2){
        //对s进行测试,测试是否满足至少一个条件
        return pre1.and(pre2).test(s);
    }
}

练习:

  • 我们给出String[] stArray
  • 通过Predicate接口获取满足条件的String并输出

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Predicate;

public class Demo2 {
    public static void main(String[] args) {
        //创造字符串对象
        String[] arr = {"芽衣,29","雷神,33","提亚娜,29"};

        //调用方法
        printInfo(arr,(String s) -> s.split(",")[0].length()>2,(String s) -> Integer.parseInt( s.split(",")[1])<30);
    }

    private static void printInfo(String[] strArray, Predicate<String> pre1,Predicate<String> pre2){
        for(String str : strArray){
            boolean b = pre1.and(pre2).test(str);
            if(b){
                System.out.println(str);
            }
        }
    }
}

Funciton接口

Function<T,R>:常用的两个方法

  • R apply(T t):将此函数应用于给定的参数
  • dafault Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
  • Function<T,R>接口常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

下面给出示例代码:

代码语言:javascript
复制
import java.util.function.Function;

public class Demo1 {
    public static void main(String[] args) {
        //方法1
        method1(100,(Integer i) -> String.valueOf(i+500));

        //方法2
        method2("200",(String s) -> Integer.parseInt(s));

        //方法3
        method3("200",(String s) -> Integer.parseInt(s),(Integer i) -> String.valueOf(i+500));
    }

    //方法1:把int类型+500转化为字符串类型
    private static void method1(int i, Function<Integer,String> fun){
        String s = fun.apply(i);
        System.out.println(s);
    }
    //方法2:把字符串类型转化为int类型
    private static void method2(String s, Function<String,Integer> fun){
        int i = fun.apply(s);
        System.out.println(s);
    }
    //方法3:把字符串类型,转化为int类型,int类型+500后转化为字符串类型输出
    private static void method3(String s, Function<String,Integer> fun1,Function<Integer ,String> fun2){
        String str = fun1.andThen(fun2).apply(s);
        System.out.println(str);
    }
}

练习:

  • 我们给出String s = “胡桃,20”;
  • 按下列步骤:
    • 将字符串截取到数字年龄部分
    • 将上一步的字符串转换为int类型
    • 将上一步的int类型+70后得到结果并输出
  • 请通过Function接口实现函数拼接
代码语言:javascript
复制
import java.util.function.Function;

public class Demo2 {
    public static void main(String[] args) {
        //调用方法:
        printInfo("胡桃,20",(String s) -> s.split(",")[1],(String s) -> Integer.parseInt(s),(Integer i) -> i + 70);
    }

    //方法
    private static void printInfo(String s, Function<String, String> fun1,Function<String,Integer> fun2,Function<Integer,Integer> fun3){
        System.out.println(fun1.andThen(fun2).andThen(fun3).apply(s));
    }
}

结束语

好的,关于函数式接口的内容就到这里

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数式接口
    • 函数式接口作为方法的参数
      • 函数式接口作为方法的返回值
        • 函数式常用接口
          • Supplier接口
          • Consumer接口
          • Predicate接口
          • Funciton接口
      • 结束语
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档