函数式接口

函数式接口

1.概述

1.1 定义

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

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

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

1.2 使用

如何检测一个接口是否为函数式接口?

  1. @FunctionalInterface
  2. 放在定义接口的上方:如果接口是函数式接口,编译通过;如果不是,编译失败

注意:

  1. 我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要满足函数式接口定义的条件,也同样是函数式接口。但是,建议加上该注解
//函数式接口:有且仅有一个抽象方法的接口
public class MyInterfaceDemo {
   
    public static void main(String[] args) {
   
        MyInterface my = () -> System.out.println("函数式接口");
        my.show();//函数式接口
    }
}

@FunctionalInterface
interface MyInterface {
   
    void show();
//    void test();
}

2.函数式接口作为参数

需求:

  1. 定义一个类(RunnableDemo),在类中提供两个方法
    1. 一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
    2. 一个是主方法,在主方法中调用startThread方法
public class RunnableDemo {
   
    public static void main(String[] args) {
   
        //在主方法中调用startThread方法
        //匿名内部类
        startThread(new Runnable() {
   
            @Override
            public 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表达式作为参数传递

  • startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
    

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

需求:

  1. 定义一个类(ComparatorDemo),在类中提供两个方法
    1. 一个方法是:Comparator getComparator() 方法返回值Comparator是一个函数式接口
    2. 一个是主方法,在主方法中调用getComparator()方法
package com.advanced.functionalinterface.demo03;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

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

        //向集合中添加元素
        arr.add("cccc");
        arr.add("bb");
        arr.add("aaa");
        arr.add("d");

        //排序前
        System.out.println("排序前:"+arr);//排序前:[cccc, bb, aaa, d]

        //使用工具类自然排序
//        Collections.sort(arr);//排序后:[aaa, bb, cccc, d]
        //使用自定义比较器排序
        Collections.sort(arr,getComparator());//排序后:[d, bb, aaa, cccc]

        //排序后
        System.out.println("排序后:"+arr);
    }

    private static Comparator<String> getComparator() {
   
        //匿名内部类
//        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();
//        };

        //Lambda简化式
        return (s1,s2) -> s1.length()-s2.length();
    }
}

通过上面练习,我们知道:

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

  • private static Comparator<String> getComparator() {
         
        return (s1,s2) -> s1.length()-s2.length();
    }
    

4.常用的函数式接口

4.1 内容

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

我们重点学习下面的4个接口:

  1. Supplier接口
  2. Consumer接口
  3. Predicate接口
  4. Function接口

4.2 Supplier接口

  • public interface Supplier:包含一个无参的方法
  • T get():获得结果
  • 该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
  • Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用
package com.advanced.functionalinterface.demo04supplier;

import java.util.function.Supplier;

public class SupplierDemo {
   
    public static void main(String[] args) {
   
        String s = getString(() -> "林青霞");
        System.out.println(s);

        Integer i = getInteger(() -> 30);
        System.out.println(i);
    }
    
    private static Integer getInteger(Supplier<Integer> i) {
   
        return i.get();
    }

    private static String getString(Supplier<String> supp) {
   
        return supp.get();
    }
}

练习:

  1. 定义一个类(SupplierTest),在类中提供两个方法
  2. 一个方法是int getMax(Supplier sup) 返回int数组中的最大值
  3. 一个是主方法,在主方法中调用getMax方法
package com.advanced.functionalinterface.demo04supplier;

import java.util.function.Supplier;

public class SupplierTest {
   
    public static void main(String[] args) {
   
        //定义一个int[]数组
        int[] arr = {
   10, 90, 30, 40, 20, 50};
        int max = getMax(() -> {
   
            int oldmax = arr[0];
            for (int i = 0; i < arr.length; i++) {
   
                if (oldmax < arr[i]) {
   
                    oldmax = arr[i];
                }
            }
            return oldmax;
        });
        System.out.println(max);
    }

    //返回int数组中的最大值
    public static int getMax(Supplier<Integer> sup) {
   
        return sup.get();
    }
}

4.3 Consumer接口

  • public interface Consumer:包含两个方法
  • void accept(T t): 对给定的参数执行此操作
  • default Consumer andThen(Consumer<? super T> after):返回一个组合的Consumer,按顺序执行该操作,然后执行after操作
  • Consumer接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
package com.advanced.functionalinterface.demo05consumer;

import java.util.function.Consumer;

public class ConsumerDemo {
   
    public static void main(String[] args) {
   
//        operatorString((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("==========");

        operatorString("林青霞",s -> System.out.println(s),s -> System.out.println(new StringBuilder(s).reverse().toString()));
    }

    //定义一个方法,用不同的方式消费同一个字符串两次
    public static void operatorString(String name,Consumer<String> con1,Consumer<String> con2) {
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值