【Java8特性】——函数式接口&方法引用

本文围绕Java展开,介绍了函数式接口,即只声明一个抽象方法的接口,可用@FunctionalInterface注解检验,还提及java.util.function包下的内置四大函数式接口。同时阐述了方法引用,它是Lambda表达式的深层次表达,包括对象实例方法、类静态方法等引用情况,还有构造器引用和数组引用。

一、函数式(Functional)接口

1. 概述

  如果一个接口中,只声明了一个抽象方法, 则这个接口就称为函数式接口。
注解:@FunctionalInterface 显式指明改接口是一个函数式接口。可以检验是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。
  可以通过Lambda表达式创建该接口的对象(若Lambda表达式抛出一个受检异常,即非运行时异常,那么该异常需要在目标接口的抽象方法上进行声明)。
  在java.util.function包下定义了java8的丰富的函数式接口。

2. Java内置四大函数式接口

在这里插入图片描述

二、方法引用

1. 方法引用

<1> 简介

  方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用,也是函数式接口的实例。
  方法引用可以看作是Lambda表达式的深层次的表达,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

<2> 使用场景

  当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。

<3> 格式

  类(对象)::方法名

<4> 情况

1. 对象 :: 实例方法
    /**
     * 情况1
     * 对象 :: 实例方法
     * Consumer 中的 void accept(T t)
     * PrintStream 中的 void printly(T t)
     */
    @Test
    public void test1() {
        Consumer<String> con1 = str -> System.out.println(str);
        con1.accept("北京");
        System.out.println("--------------------------");

        Consumer<String> con2 = System.out::println;
        con2.accept("南京");
    }

    /**
     * 情况1
     * 对象 :: 实例方法
     * Supplier 中的 T get();
     * Employee 中的 String getName()
     */
    @Test
    public void test2() {
        Employee emp = new Employee(1001, "tom", 22, 100.22);
        Supplier<String> sup1 = () -> emp.getName();
        System.out.println(sup1.get());

        System.out.println("--------------------------");
        Supplier<String> sup2 = emp::getName;
        System.out.println(sup2.get());
    }

2. 类 :: 静态方法
    /**
     * 情况2
     * 类 :: 静态方法
     * Comparator 中的 int compare(T o1, T o2);
     * Integer 中的 int compare(int x, int y)
     */
    @Test
    public void test3() {
        Comparator<Integer> comparator1 = (t1, t2) -> Integer.compare(t1, t2);
        System.out.println(comparator1.compare(11112, 123));

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

        Comparator<Integer> comparator2 = Integer::compare;
        System.out.println(comparator2.compare(12, 123));

    }
    /**
     * 情况2
     * 类 :: 静态方法
     * Function 中的  R apply(T t)
     * Math 中的 long round(double a)
     */
    @Test
    public void test4() {
        Function<Double, Long> function1 = d -> Math.round(d);
        System.out.println(function1.apply(100.49));
        System.out.println("--------------------------");
        Function<Double, Long> function2 = Math::round;
        System.out.println(function2.apply(101.6));
    }

3. 类::实例方法

  Lambda 有两个参数, 但方法引用中只有一个参数,其中 Lambda的第一个参数作为调用者

    /**
     * 情况3
     * 类::实例方法
     * Lambda 有两个参数, 但方法引用中只有一个参数,其中 Lambda的第一个参数作为调用者
     * Comparator 中的 int compare(T o1, T o2);
     * String 中的 int t1.compartTo(t2);
     */
    @Test
    public void test5() {
        Comparator<String> comparator1 = (t1, t2) -> t1.compareTo(t2);
        System.out.println(comparator1.compare("1233", "1233"));

        System.out.println("--------------------------");
        Comparator<String> comparator2 = String::compareTo;
        System.out.println(comparator2.compare("12332", "1233"));
    }

  Lambda 有一个参数, 但方法引用中没有参数, Lambda的参数作为调用者

    /**
     * Lambda 有一个参数, 但方法引用中没有参数, Lambda的参数作为调用者
     * Function 中的  R apply(T t)
     * Employee 中的 String getName()
     */
    @Test
    public void test7() {
        Employee emp = new Employee(1001, "tom", 22, 100.22);
        Function<Employee, String> function1 = e -> e.getName();
        System.out.println(function1.apply(emp));
        System.out.println("--------------------------");
        Function<Employee, String> function2 = Employee::getName;
        System.out.println(function2.apply(emp));
    }

2. 构造器引用

<1> 无参Lambda ,无参构造器

    /**
     * 构造器引用 , 无参构造器
     * Supplier 中的 T get();
     */
    @Test
    public void test1() {

        Supplier<Employee> supplier1 = () -> new Employee();
        Employee employee1 = supplier1.get();
        System.out.println(employee1);
        System.out.println("--------------------------------------------------------------------");

        Supplier<Employee> supplier2 = Employee::new;
        Employee employee2 = supplier2.get();
        System.out.println(employee2);
    }

<2> 一个参数Lambda ,一个参数构造器

 /**
     * 构造器引用 , 一个参数构造器
     * Function 中的  R apply(T t);
     */
    @Test
    public void test2() {
        Function<Integer, Employee> function1 = id -> new Employee(id);
        Employee employee1 = function1.apply(2);
        System.out.println(employee1);
        System.out.println("--------------------------------------------------------------------");
        Function<Integer, Employee> function2 = Employee::new;
        Employee employee2 = function2.apply(3);
        System.out.println(employee2);
    }

<3>二个参数Lambda ,二个参数构造器

   /**
     * 构造器引用 , 二个参数构造器
     */
    @Test
    public void test3() {
        BiFunction<Integer, String, Employee> biFunction1 = (id, name) -> new Employee(id, name);
        Employee employee1 =  biFunction1.apply(2, "jack");
        System.out.println(employee1);
        System.out.println("--------------------------------------------------------------------");

        BiFunction<Integer, String, Employee> biFunction2 = Employee::new;
        Employee employee2 = biFunction2.apply(3, "tom");
        System.out.println(employee2);
    }

3. 数组引用

  数组引用 可以看作是一个特殊的类

/**
     * 数组引用
     * 数组引用 可以看作是一个特殊的类
     * Function 中的  R apply(T t);
     *
     */
    @Test
    public void test4() {

        Function<Integer, String[]> function1 = length -> new String[length];
        String[] array1 = function1.apply(10);
        System.out.println(array1.length);
        System.out.println("--------------------------------------------------------------------");

        Function<Integer, String[]> function2 = String[]::new;
        String[] array2 = function2.apply(13);
        System.out.println(array2.length);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值