欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-22 16:01:14
...

我们先来看一下Java8 内置的四大核心函数式接口结构

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

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

我们知道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;
如下图java8新特性总结——lambda表达式之方法引用与构造器引用
使用构造器和方法引用大体就是这样,需要注意的就是使用时参数列表以及返回值需一致