java8新特性之函数式接口


什么是函数式接口?

如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口
可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)
可以在一个接口上使用@FunctionalInterface注解,来检查他是否式一个函数式接口。

在java.util.function包下定义了java8的丰富的函数式接口。

自定义函数式接口:

/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 9:43
 * @Description: FunctionalInterface : 检验FuncInterface 是否为函数式接口
 */
@FunctionalInterface
public interface FuncInterface {
    void test();
//    void test1();
}

在Java8中Lambda表达式就是一个函数式接口的实例

java内置四大核心函数式接口

函数式接口参数类型返回类型用途
Consumer < T > 消费型接口Tvoid对类型为T的对象应用操作,包含方法 void accept(T t)
Supplier < T > 供给型接口T返回类型为T的对象,包含方法 T get()
Function < T > 函数型接口TR对类型为T的对象应用操作,并返回结果是R类型的对象,包含方法 R apply(T t)
Predicate < T > 断定型接口Tboolean对类型为T的对象应用操作,并返回boolean值,包含方法 boolean test(T t)
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 9:45
 * @Description: TODO
 */
public class LambdaDemo2 {
    @Test
    public void test1(){
        happyTime(500, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("学习消费价格:"+aDouble);
            }
        });
        System.out.println("-------------");
        happyTime(300, money->  System.out.println("娱乐消费价格:"+money));

    }
    public void happyTime(double money, Consumer<Double> con){
        con.accept(money);
    }

    @Test
    public void test2(){
        List<String> list = Arrays.asList("东京","北京","南京","西京","天津");
        List<String> strings = filterString(list, new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("京");
            }
        });
        System.out.println(strings);
        System.out.println("-------------");
        List<String> strings2 = filterString(list, s-> s.contains("京"));
        System.out.println(strings2);


    }

    public List<String> filterString(List<String> list, Predicate<String> pre){
        ArrayList<String> filterStr= new ArrayList<>();

        for (String s:list) {
            if(pre.test(s)){
                filterStr.add(s);
            }
        }
        return filterStr;
    }
}

方法引用与构造器引用

方法引用

什么是方法引用:
当要传递给Lambda体的操作,应有实现的方法了,可以使用方法引用!
方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

要求:
实现接口的抽象方法的参数泪飙和返回值类型,必须与方法引用的方法参数列表和返回值类型保持一致!

格式:
使用操作符 “::” 将类(或对象)与方法名分隔开来。

主要使用情况:

  • 对象::实例方法名
  • 类::静态方法名
  • 类::实例方法名
import org.junit.Test;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
/**
 * @Author: mei_ming
 * @DateTime: 2022/6/3 10:14
 * @Description: 方法引用
 */
/**
 * 使用情景: 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
 *
 * 方法引用,本质上就是Lambda表达式,而lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例
 *
 * 使用格式:类(或对象) :: 方法名
 *
 * 情况1   对象 :: 非静态方法
 * 情况2   类 :: 静态方法
 * 情况3   类 :: 非静态方法
 *
 * 方法引用的使用要求:要求接口中的抽象方法的形参列表和返回值类型与方法应用的方法的形参列表和返回值类型相同!(针对情况1和2)
 *
 */
public class LambdaDemo3 {
    // 一、对象 :: 非静态方法
    // Consumer中的 void accept(T t)
    // PrintStream中的void println(T t)
    @Test
    public void test1(){
        Consumer<String> con1 =str-> System.out.println(str);
        con1.accept("北京");
        System.out.println("-------------");
        PrintStream ps = System.out;
        Consumer<String> con2 = ps :: println;
        con2.accept("beijing");
    }

    //二、类::静态方法
    //Comparator中的int compare(T t1,T t2)
    //Integer中的int compare(T t1,T t2)
    @Test
    public void test2(){
        Comparator<Integer> com1=(t1,t2)->Integer.compare(t1,t2);
        System.out.println(com1.compare(12,21));
        System.out.println("-------------");
        Comparator<Integer> com2= Integer::compare;
        System.out.println(com2.compare(12,6));
    }

    //Function中的R apply(T t)
    //Math中的Long round(Double d)
    @Test
    public void test3(){
        Function<Double,Long> fun1=d -> Math.round(d);
        System.out.println(fun1.apply(12.3));
        System.out.println("-------------");
        Function<Double,Long> fun2 = Math::round;
        System.out.println(fun2.apply(12.6));
    }

    //三、类::非静态方法
    //Comparator中的int compare(T t1,T t2)
    //String中的int t1.compare(t2)
    @Test
    public void test4(){
        Comparator<String> com1=(t1,t2)->t1.compareTo(t2);
        System.out.println(com1.compare("abc","abd"));
        System.out.println("-------------");
        Comparator<String> com2= String::compareTo;
        //                       这个String 是 上面t1类型的返回值
        System.out.println(com2.compare("abc","abe"));
    }
}

构造器引用与数组引用

import org.junit.Test;

import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 *
 * 1. 构造器引用
 *      和方法引用类似,函数式接口的抽象方法的形参列表和构造器中的形参列表一致
 *      抽象方法的返回值级构造器所属的类的类型
 *
 * 2. 数组引用
 *      看成一个特殊的类
 */
public class LambdaDemo4 {
    //一、构造器引用
    //Supplier中的T get()
    //Cat的 Cat()
    @Test
    public void test1(){
        //原始
        Supplier<Cat> sup = new Supplier<Cat>() {
            @Override
            public Cat get() {
                return new Cat();
            }
        };
        sup.get();
        System.out.println("---------");
        //lambda
        Supplier<Cat> sup1 = ()-> new Cat();
        sup1.get();
        System.out.println("---------");
        //构造器引用
        Supplier<Cat> sup2 = Cat::new;
        sup2.get();
    }

    //Function中R apply(T t)
    //Cat的 Cat(String name)
    @Test
    public void test2(){
        //lambda
        Function<String,Cat> fun1 = (name)-> new Cat(name);
        Cat cat = fun1.apply("小花");
        System.out.println(cat);
        System.out.println("---------");
        //构造器引用
        Function<String,Cat> fun2 =Cat::new;
        Cat cat1 = fun2.apply("小草");
        System.out.println(cat1);
    }

    //BiFunction中R apply(T t,U u)
    //Cat的 Cat(String name)
    @Test
    public void test3(){
        //lambda
        BiFunction<String,Integer,Cat> fun1 = (name,age)-> new Cat(name,age);
        Cat cat = fun1.apply("小花",1);
        System.out.println(cat);
        System.out.println("---------");
        //构造器引用
        BiFunction<String,Integer,Cat> fun2 =Cat::new;
        Cat cat1 = fun2.apply("小草",2);
        System.out.println(cat1);
    }

    //二、数组引用
    //Function中的R apply(T t)
    @Test
    public void test4(){
        //lambda
        Function<Integer,String[]> fun1=length->new String[length];
        String[] str1 = fun1.apply(5);
        System.out.println(Arrays.toString(str1));

        System.out.println("---------");

        //数组引用
        Function<Integer,String[]> fun2=String[]::new;
        String[] str2 = fun2.apply(10);
        System.out.println(Arrays.toString(str2));
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值