Java8新特性-004-方法、构造器、数组引用

方法引用

  • 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!)
  • 方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。
  • 如下三种主要使用情况:
1.对象::实例方法 
2.类::静态方法
3.类::实例

微信公众号:JavaWeb架构师
微信公众号:JavaWeb架构师

应用条件

  • 对象::实例方法名、类::静态方法名——应用条件:
    要实现的Lambda表达式中的抽象方法具体实现的时候调用了另外一个对象的方法(类的静态方法),如果这两个方法(自己的抽象方法、另一个对象的方法)的参数和返回值一致,那么可以直接使用。

    总结:参数和返回值类型一致。

  • 类::实例方法名——应用条件;
    Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这个实例方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用(类名::实例方法名指的是第一个参数的类和实例方法)。

    如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2),其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;

    总结:
    - 参数一作为实例方法的调用者;
    - 参数二作为实例方法的参数;
    - 返回值类型和Lambda表达式一致;

测试代码

TestMethodRef.java

package java8.method.constructor;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import org.junit.Test;

public class TestMethodConstructor {
    /**
     * 方法的引用:
     *  1.若Lambda中的内容有方法已经实现了,那么我们可以使用“方法引用”,
     *      可以理解为方法引用是Lambda表达式的另外一种形式
     *  2.方法引用的三种形式:
     *      2.1.对象::实例方法名
     *      2.2.类::静态方法名
     *      2.3.类::实例方法名
     *  3.应用条件
     *      3.1.对象::实例方法名、类::静态方法名——应用条件:
     *          要实现的Lambda表达式中的抽象方法具体实现的时候调用了另外一个对象的方法(类的静态方法),
     *          如果这两个方法(自己的抽象方法、另一个对象的方法)的参数和返回值一致,
     *          那么可以直接使用。
     *          总结:参数和返回值类型一致。
     *      3.2.类::实例方法名——应用条件;
     *          Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这
     *          个实例方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用
     *          (类名::实例方法名指的是第一个参数的类和实例方法)。
     *          如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2);
     *          其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;
     *          总结:
     *              - 参数一作为实例方法的调用者;
     *              - 参数二作为实例方法的参数;
     *              - 返回值类型和Lambda表达式一致;
     */

    /**
     * 2.1.对象::实例方法名
     */
    @Test
    public void testMethodRef1() {
        PrintStream out = System.out;
        /**
         *  Lambda对象 = 另一个对象::另一个对象符合要求的方法名。
         */

        /**
         * 参数和返回值一致:
         * accept: void accept(String str);
         * println: void println(String str);
         */
        Consumer<String> consumer = out::println;

        consumer.accept("对象::实例方法名!");
    }

//  
    /**
     * 2.2.类::静态方法名
     */
    /**
     * 规则和2.1类似,都是参数和返回值对应
     */
    @Test
    public void testMethodRef2() {
        /**
         * 同样的,参数和返回值要一致:
         * int Comparator.compare(Integer i1, Integer i2)
         * int Integer.compare(Integer i1, Integer i2)
         */
        Comparator<Integer> comparator = Integer::compare;


        TreeSet<Integer> treeSetInteger = new TreeSet<>(comparator);
        treeSetInteger.add(10);
        treeSetInteger.add(-1);
        treeSetInteger.add(20);
        Iterator<Integer> iterator = treeSetInteger.iterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next() + "\t");
        }
    }
//
    /**
     * 2.3.类::实例方法名
     */
    /**
     * 应用条件:
     *  Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这个实例
     *  方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用(类名::实例方法名
     *      指的是第一个参数的类和实例方法)。
     *  如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2);
     *      其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;
     */
    @Test
    public void testMethodRef3() {
        /**
         * 参数和返回值一致:
         *  - 参数一作为实例方法的调用者;
         *  - 参数二作为实例方法的参数;
         *  - 返回值类型和Lambda表达式一致;
         */
        BiPredicate<String, String> biPredicate = String::equals;
        System.out.println(biPredicate.test("中国", "日本"));
    }
}

微信公众号:JavaWeb架构师

构造器引用

  • 格式: ClassName::new
  • 与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致!

微信公众号:JavaWeb架构师

测试代码

TestConstuctorRef.java

package java8.method.constructor;

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

import org.junit.Test;

public class TestConstuctorRef {

    /**
     * 构造器引用:
     *   1.格式:
     *      类名::new
     *   2.应用条件
     *      Lambda表达式的内容刚好只有这一个新建对象的语句,新建的对象也刚好是这个Lambda
     *      表达式的返回值,并且Lambda表达式的参数刚好是新建对象的构造器的参
     *      数(对应去调用这个构造器)。  
     */

    @Test
    public void testConstructor1() {
        /**
         * 应用条件:
         *  1.新建的对象刚好是Lambda表达式的返回值类型;
         *  2.Lambda表达式的参数刚好是这个构造器的参数值(对应去调用这个构造器);
         */
        // 对应:空参构造器
        Supplier<Person> supplierPerson = Person::new;

        System.out.println(supplierPerson.get());

        // 对应:一个参数的构造器,String
        Function<String, Person> functionPerson = Person::new;  // <String, Person> -->参数,返回值
        System.out.println(functionPerson.apply("周杰伦"));
    }
}

class Person {
    private String name = "冯强";

    // 构造器一
    public Person() {

    }

    // 构造器二
    public Person(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
}

微信公众号:JavaWeb架构师

数组引用

  • 格式: 数组类型[] :: new
    微信公众号:JavaWeb架构师

测试代码

TestArrayRef.java

package java8.method.constructor;

import java.util.function.Function;

import org.junit.Test;

public class TestArrayRef {
    /**
     * 数组引用:
     *  1.格式
     *      数组类型[]::new;
     *  2.引用条件:
     *      和构造器引用的条件是一样的(返回值类型,参数对应构造器),只是写法是专有的。
     */
    @Test
    public void testArrayRef() {
        /**
         * String[] apply(Integer i); --> String[]::new; --> new String(i);
         */
        Function<Integer, String[]> functionStringArray = String[]::new;

        String[] apply = functionStringArray.apply(10);
        System.out.println("数组长: " + apply.length);
    }
}

微信公众号:JavaWeb架构师


其它

  • 源码下载
关注下方公众号,回复:Java8.code

完整教程PDF版本下载

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值