函数式接口

一. 函数式接口简介

1.什么是函数式接口?

在接口中,有且只有一个抽象方法,那么这个接口就是函数式接口。函数式接口是Lambda表达式使用的前提条件。

2.为什么要使用函数式接口?

在Java中不支持将函数作为一个数据,也就不能将函数作为方法的参数进行传递。因此给函数外加一层接口的声明,相当于为其穿上一件漂亮的外衣包装起来,如果需要将函数作为方法传递时,就可以传递函数所在接口的实现类对象,来间接的传递方法内容了。

3.函数式接口定义

使用@FunctionalInterface注解来检查一个接口是否是一个函数式接口。放在接口定义的上方,如果接口是函数式接口,编译通过;如果不是,则编译失败

二. 函数式接口案例

2.1 定义函数式接口


@FunctionalInterface
public interface MyFunctionInterface {
    void show();
}

2.2 使用函数式接口

public class UserFunctionInterface {
        //定义一个方法以函数式接口作参数
    public static void test(MyFunctionInterface myfun){
        myfun.show();
    }
        //程序入口
    public static void main(String[] args) {
        //1.使用匿名内部类的方式
        MyFunctionInterface myfun = new MyFunctionInterface() {
            @Override
            public void show() {
                System.out.println("使用匿名内部类的方式实现函数式接口....");
            }
        };
        
        test(myfun);

        //2.直接传递匿名内部类
        test(new MyFunctionInterface() {
            @Override
            public void show() {
                System.out.println("使用直接传递匿名内部类的方式....");
            }
        });

        //3.使用Lambda表达式的方式使用函数式接口
        test(()-> System.out.println("使用Lambda表达式的方式使用函数式接口..."));
    }
}

三. 常用函数式接口

Java8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk8中提供的即可。

1.消费型接口

内部包含一个void accept(T t)方法,是一个有参无返回值的方法。其消费数据的数据类型由泛型决定。我们可以定义一个方法,体现不同客户对X元现金的不同消费情况进行描述,即将消费金额和消费方式都以方法参数的形式进行传递。具体需求如下:

public class TestConsumer {
    //定义方法实现用户消费的功能
    public static void userConsumer(Double money,Consumer<Double> con){
        con.accept(money);
}
    //测试
public static void main(String[] args) {
        //客户1:花了X元, 买了一盒化妆品
        userConsumer(500.0,money -> System.out.println("客户1花了"+money+"买了一盒化妆品"));

        //客户2:花了X元, 吃了一顿美食
        userConsumer(800.0,money -> System.out.println("客户2花了"+money+"元钱吃了一顿美食"));
    }  
}

2.供给型接口

内部包含一个T get()方法,是一个无参有返回值的方法。根据用户指定的接口泛型类型,生产泛型类型的数据提供给我们。

public class TestSupplier {
    public static void main(String[] args) {
        //1.客户1 : 要5个1-10之间的随机数整数
        List<Integer> list1 = useSupplier(5, new Supplier<Integer>() {
            @Override
            public Integer get() {
                return (int) (Math.random() * 10 + 1);
            }
        });
        
        System.out.println(list1);

        //2.客户2 : 要8个1-100之间的偶数
        List<Integer> list2 = useSupplier(8, () -> {
            int num = (int) (Math.random() * 100 + 1);
            if (num % 2 == 0) {
                return num;
            } else {
                return num + 1;
            }
        });
        
        System.out.println(list2);
    }
    /*
    * 根据客户需求,返回n个满足某个规律的数
    * */
    public static List<Integer> useSupplier(int count, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            Integer integer = sup.get();
            list.add(integer);
        }
        return list;
    }
}

3.函数型接口

内部包含一个R apply(T t)方法,是一个有参有返回值的方法。通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值。这里我们也可以定义一个方法,给定一个整数x,根据Lambda表达式的实现转换成对应的y,具体需求如下:

public class TestFunction {
    public static void main(String[] args) {
        // 1)客户1 : y为x的2倍
        System.out.println(useFunction(5, x -> x * 2));// 10

        // 2) 客户2 : y为x的平方
        System.out.println(useFunction(-9, x -> x * x));// 81
    }
    /*
    * 根据x计算y
    * 参数x代表用户传递的数
    * 参数2代表用户要求得到结果的实现方式
    * */
    public static int useFunction(int x, Function<Integer, Integer> fun) {
        return fun.apply(x);
    }
}

4.断言型接口

内部包含一个boolean test(T t)方法,对给定的参数进行判断(判断逻辑由Lambda表达式实现),如果符合要求返回true,不符合则返回false。

这里也定义一个方法,需要用户提供一个容器ArrayList<Integer>,根据用户的需求,将容器中符合条件的数据筛选出来,将筛选出的数据放置在新容器中返回给用户。具体需求如下:

public class TestPredicate {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(12);
        list1.add(11);
        list1.add(120);
        list1.add(111);
        list1.add(67);
        list1.add(88);
        // 1)客户1 : 要求容器中的所有数, 都能被2整除
        System.out.println(usePredicate(list1,x->x%2==0));// [12, 120, 88]
        // 2)客户2 : 要求所有的数据都不大于100
        System.out.println(usePredicate(list1,x->x < 100));// [12, 11, 67, 88]
    }
    /*
    * 对客户提交的数据进行过滤处理
    * */
    public static ArrayList<Integer> usePredicate(ArrayList<Integer> list1, Predicate<Integer> pre){
        ArrayList<Integer> list = new ArrayList<>();
        for(Integer i : list1){
            //过滤处理,符合条件的数据放到新集合中
            if(pre.test(i)){
                list.add(i);
            }
        }
        //返回新集合
        return list;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值