您的位置:首页 > 编程语言 > Java开发

java8新特性总结——lambda表达式之方法引用与构造器引用

2018-03-28 20:41 1006 查看
我们先来看一下Java8 内置的四大核心函数式接口结构









我们知道lambda表达式需要函数式接口的支持,即只有一个抽象方法的接口的支持。使用Lambda表达式语法即可优雅的完成功能。现在介绍Lambda表达式的另外的表现形式。还是先贴一段代码强化一下理解。package com.atguigu.test;

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

import org.junit.Test;

import com.atguigu.java8.Employee;

public class TestRef {
//对象的引用 :: 实例方法名
@Test
public void test1() {
//在没有lambda表达式之前,如果我们想使用某个接口的一个方法,
//例如Consumer<T>消费型接口的accept(T)方法,通常做法如下
//①创建Consumer接口的匿名对象,
//或者写个类实现这个接口的方法,然后用该类的对象调用accept
Consumer<String> con1=new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t);
}
};
con1.accept("我爱学习java");
System.out.println("----------------------");
//现在有了lambda表达式,可以进行优雅的简化
Consumer<String> con2=(str) -> System.out.println(str);
con2.accept("我也爱学习java");
//现在要说的是lambda表达式的另一种形式,不同于上面的使用箭头操作符的形式
//这种形式同样能达到相同效果
//注意Consumer接口的accept方法接受一个参数没有返回值
//同样的System.out也就是PrintStream的println此刻用的也是一个参数无返回值的方法(虽然方法重载)
Consumer<String> con3=System.out::println;
System.out.println("----------------------");
con3.accept("怎么能少的了我呢");
}

@Test
public void test2() {
Employee emp=new Employee(101,"张三",20,9999);
Supplier<String> sup1=new Supplier<String>() {
@Override
public String get() {
return emp.getName();
}
};
System.out.println(sup1.get());
Supplier<String> sup2=()->emp.getName();
System.out.println(sup2.get());
Supplier<Integer> sup3=emp::getAge;
System.out.println(sup3.get());
}

//类名 :: 静态方法名
@Test
public void test3() {
Comparator<Integer> com=(x,y)->Integer.compare(x, y);
System.out.println(com.compare(20, 30));
System.out.println("-------------");
Comparator<Integer> com2=Integer::compare;
System.out.println(com2.compare(20, 30));
}

//类名 :: 实例方法名
@Test
public void test4() {
Function<Employee, String> f1=Employee::getName;//传一个T(Employee)返回一个R(String)
System.out.println(f1.apply(new Employee()));
Function<Employee, Integer> f2=Employee::getAge;//传一个T(Employee)返回一个R(Integer)
System.out.println(f2.apply(new Employee()));
}

//构造器引用 类名 :: new
@Test
public void test5() {
Function<String, Employee> f1=Employee::new;
//传入一个String 返回一个Employee对象,此时需要有构造器public Employee(String name) {}
System.out.println(f1.apply("王五"));

}
//数组引用 类型[] :: new
@Test
public void test6() {
Function<Integer, String[]> f=String[]::new;
System.out.println(f.apply(10).length);
}
}
具体规则总结如下:
* 一、方法引用:若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用
* 			  (可以将方法引用理解为 Lambda 表达式的另外一种表现形式)
* 1. 对象的引用 :: 实例方法名
* 2. 类名 :: 静态方法名
* 3. 类名 :: 实例方法名
* 注意:
* 	 ①方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
* 	 ②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
* 二、构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!
* 1. 类名 :: new
* 三、数组引用
* 	类型[] :: new;
如下图

使用构造器和方法引用大体就是这样,需要注意的就是使用时参数列表以及返回值需一致
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息