java8新特性专题之四、lambda方法引用和构造器引用

方法引用例子1

  • landscape
    Java8的lambda引入了三种方法引用,构造器引用,及数组引用,以减少代码的开发。需要注意的是,如果需要使用此特性,必须方法返回值类型、参数数量与类型与函数式接口保持一致。

  • 实例
  1. 对象 - 实例方法使用场景
    当对象的实例方法已经实现了函数式接口将要实现的功能,且实例方法的参数数量、参数类型、返回类型与函数式接口一致时,可以使用此特性。使用方式为:
    对象::方法名
/**
 * @author: zhuocc2
 * @date: 2019-09-02 4:53:18 PM
 * @Package: lambda
 * @Description: 对象 - 实例方法 使用场景。
 *  当已经实例的方法已经实现了lambda将要实现的功能,可以使用此方式。
 *  但需要lambda函数式接口的参数与返回值与实例方法的参数与返回值相同
 *  使用方式 对象::方法名
 */
@Test
public void objectInstance() {
    PrintStream sysOut = System.out;
        
    Consumer<String> consumer = sysOut::println;
    consumer.accept("对象-实例方法运用");
}

输出
对象-实例方法运用


  1. 类 - 静态方法使用场景
    当类的静态方法已经实现了函数式接口将要实现的功能,且实例方法的参数数量 、参数类型、返回类型与函数式接口一致时,可以使用此特性。使用方式为:
    类::方法名
/**
 * @author: zhuocc2
 * @date: 2019-09-02 5:27:39 PM
 * @Package: lambda
 * @Description: TODO 类 - 静态方法 使用场景
 *  当类里已经实现了lambda将要实现的功能,可以使用此方式。只需参数与返回与lambda函数式接口保持一致即可。
 *  使用方式 类名::方法名
 */
@Test
public void classStaticMethod() {
    Comparator<Integer> comparator = Integer::compare;
    System.out.println(comparator.compare(2, 1));
}

输出
1


  1. 类 - 实例方法使用场景
    当实例方法的第一个参数为实例方法的调用者,第二个参数为实例方法的参数时,且实例方法的参数数量与类型、返回值类型与函数式接口一致时,可以使用此特性。使用方式为:
    类::方法名
@Test
public void classInstance() {
    BiPredicate<String, String> bp = String::equals;
        
    boolean test = bp.test("2", "2");
    System.out.println(test);
}

输出
true


  1. 构造器引用使用场景
    当构造器的参数列表与函数式接口的参数列表一致时,可以使用此特性。使用方式为:
public class TestConstruct {

    private String str = null;
    
    public TestConstruct(String str) {
        this.str = str;
        System.out.println(str);
    }
    
    public TestConstruct(String str1, String str2) {
        System.out.println(str1 + str2);
    }
    
    public String getStr() {
        return this.str;
    }
}
/**
 * @author: zhuocc2
 * @date: 2019-09-03 9:24:04 PM
 * @Package: lambda
 * @Description: TODO 构造器引用
 */
@Test
public void constructReference() {
    Function<String, TestConstruct> fun = TestConstruct::new;
    TestConstruct construct = fun.apply("str");
    System.out.println(construct.getStr());
}
输出
str
str
  1. 数组引用
/**
 * @author: zhuocc2
 * @date: 2019-09-03 9:30:22 PM
 * @Package: lambda
 * @Description: TODO 数组引用
 */
@Test
public void arrayReference() {
        
    Function<Integer, Float[]> fun = Float[]::new;
    Float[] array = fun.apply(20);
    System.out.println(array.length);   
}

输出
20

方法引用例子2

一、 方法引用: 若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”

要求 方法的参数和返回值类型  和 函数式接口中的参数类型和返回值类型保持一致。

主要有三种语法格式:

对象 :: 实例方法名

Consumer<String> consumer1 = System.out::print;   //通过 方法引用 实现Lambda体。
consumer1.accept("Hello World!");

类 :: 静态方法名

Comparator<Integer> comparator1 = Integer::compare;  等价于
Comparator<Integer> comparator2 = (x, y) -> Integer.compare(x,y);

类 :: 实例方法名

//Lambda表达式参数列表中的第一个参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用 类名 :: 方法名
BiPredicate<String, String> biPredicate = (x,y) -> x.equals(y);
BiPredicate<String,String> biPredicate1 = String :: equals;      
 

 二、构造器引用:  构造器中的参数类型和函数式接口中的参数类型一致。

Supplier<Date> supplier = Date :: new;
Date date = supplier.get();
long time = date.getTime();

三、数组引用

Function<Integer, String[]> function =  String[]::new;
String[] apply = function.apply(10);
System.out.println(apply.length); // 10

方法引用例子3

当要传递给Lambda体的操作,已经有实现的方法,就可以使用方法引用!
实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致
方法引用使用操作符“::”将方法名和对象或者类的名字分隔开来。
三种使用情况:

  • 对象::实例方法
  • 类::静态方法
  • 类::实例方法

例如:

(x)->System.out.println(x);

等同于:

System.out::println;

例如:

BinaryOperator<Double> bo=(x,y)->Math.pow(x,y)

等同于:

BinaryOperator<Double> bo=Math::pow;

例如:

compare((x,y)->x.equals(y),“abcdef”,“abcdef”);

等同于

compare(String::equals,“abcdef”,“abcdef”);

注意:当需要引用方法的第一个参数是调用对象,并且第二个参数是需要引用方法的第二个参数(或无参数)时:ClassName::mothodName

构造器引用

格式:ClassName::new

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

例如:

Function<Integer,MyClass> fun=(n)->new MyClass(n);

等同于:

Function<Integer,MyClass> fun=MyClass::new;

数组引用

格式:type[]::new

例如:

Function<Integer,Integer[]> fun=(n)->new Integer[n];

等同于:

Function<Integer,Integer[]> fun=Integer[]::new;

 

    @Test
    public void test6() {
        /*************** 方法的引用 ****************/
        // 类::静态方法名
        Comparator<Integer> bb = Integer::compare;
        System.out.println(bb.compare(3, 2));
        Comparator<Integer> cc = (x, y) -> Integer.compare(x, y);
        System.out.println(cc.compare(3, 2));
 
        Comparator<Integer> dd = (x, y) -> x.compareTo(y);
        System.out.println(dd.compare(3, 2));
        Comparator<Integer> ee = Integer::compareTo;
        System.out.println(ee.compare(3, 2));
        // 类::实例方法名
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);
        System.out.println(bp.test("a", "b"));
        BiPredicate<String, String> bp1 = String::equals;
        System.out.println(bp1.test("a", "b"));
 
        // 对象::实例方法名
        Consumer<String> con1 = x -> System.out.println(x);
        con1.accept("abc");
        Consumer<String> con = System.out::println;
        con.accept("abc");
 
        Emp emp = new Emp("上海", "xiaoMIng", 18);
        Supplier<String> supper1 = () -> emp.getAddress();
        System.out.println(supper1.get());
        Supplier<String> supper = emp::getAddress;
        System.out.println(supper.get());
 
        /*************** 构造器的引用 ****************/
        // 无参构造函数,创建实例
        Supplier<Emp> supper2 = () -> new Emp();
        Supplier<Emp> supper3 = Emp::new;
        Emp emp1 = supper3.get();
        emp1.setAddress("上海");
        // 一个参数
        Function<String, Emp> fun = address -> new Emp(address);
        Function<String, Emp> fun1 = Emp::new;
        System.out.println(fun1.apply("beijing"));
        // 两个参数
        BiFunction<String, Integer, Emp> bFun = (name, age) -> new Emp(name, age);
        BiFunction<String, Integer, Emp> bFun1 = Emp::new;
        System.out.println(bFun1.apply("xiaohong", 18));
 
    }
 
    static class Emp {
        private String address;
 
        private String name;
 
        private Integer age;
 
        public Emp() {
 
        }
 
        public Emp(String address) {
            this.address = address;
        }
 
        public Emp(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
 
        public Emp(String address, String name, Integer age) {
            super();
            this.address = address;
            this.name = name;
            this.age = age;
        }
 
        public String getAddress() {
            return address;
        }
 
        public void setAddress(String address) {
            this.address = address;
        }
 
        public String getName() {
            return name;
        }
 
        public void setName(String name) {
            this.name = name;
        }
 
        public Integer getAge() {
            return age;
        }
 
        public void setAge(Integer age) {
            this.age = age;
        }
 
        @Override
        public String toString() {
            return "Emp [address=" + address + ", name=" + name + ", age=" + age + "]";
        }
 
    }

 

 

作者:十七家的猫
链接:https://www.jianshu.com/p/f2ab2db6fe2b
来源:简书

 

posted @ 2022-03-05 23:57  程序员小明1024  阅读(74)  评论(0编辑  收藏  举报