Java8新特性_方法引用与构造器引用

本文详细介绍了Java 8中的方法引用和构造器引用特性,包括对象引用的实例方法名、类名的静态方法名、类名的实例方法名以及构造器引用的使用方式,并通过示例代码进行演示。此外,还涵盖了数组引用的使用。内容旨在帮助读者深入理解Java 8的新特性,提升代码简洁性。

package com.zs.boot.controller;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

import org.junit.Test;

/*
 * 一、方法引用:若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用
 * 			  (可以将方法引用理解为 Lambda 表达式的另外一种表现形式)
 * 
 * 1. 对象的引用 :: 实例方法名
 * 
 * 2. 类名 :: 静态方法名
 * 
 * 3. 类名 :: 实例方法名
 * 
 * 注意:
 * 	 ①方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
 * 	 ②若Lambda的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
 * 
 * 二、构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!
 * 
 * 1. 类名 :: new
 * 
 * 三、数组引用
 * 
 * 	类型[] :: new;
 * 
 * 
 */
public class TestMethodRef {

	public class Employee{
		private String name;
		private int age;
		private double salary;

		public Employee() {
		}

		public Employee(int age) {
			this.age = age;
		}

		public Employee(String name, int age) {
			this.name = name;
			this.age = age;
		}

		public Employee(String name, int age, double salary) {
			this.name = name;
			this.age = age;
			this.salary = salary;
		}

		public String show() {
			return "测试方法引用!";
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}

		public double getSalary() {
			return salary;
		}

		public void setSalary(double salary) {
			this.salary = salary;
		}

		@Override
		public String toString() {
			return "Employee{" +
					"name='" + name + '\'' +
					", age=" + age +
					", salary=" + salary +
					'}';
		}
	}

	List<Employee> employees = Arrays.asList(
			new Employee("刘德华",48,8000),
			new Employee("张学友",28,8500),
			new Employee("黎明",45,6500),
			new Employee("郭富城",51,5500));

	@Test
	public void test1(){
		Consumer<String> con = (str) -> System.out.println(str);
		con.accept("你好!");
		/*
		方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
		println里面是:
		public void println(String x) {
			synchronized (this) {
				print(x);
				newLine();
			}
		}
		Consumer里面是:
		void accept(T t);*/

		PrintStream ps = System.out;
		Consumer<String> con1 = ps::println;
		con1.accept("大家好");

		//最终版,对象的引用 :: 实例方法名
		Consumer<String> con2 = System.out::println;
		con2.accept("Hello Java8!");
	}

	//--------------------------------------------------------------------

	//对象的引用 :: 实例方法名
	@Test
	public void test2(){
		Employee emp = new Employee("周华健", 55, 9999);

		Supplier<String> sup = () -> emp.getName();
		String str = sup.get();
		System.out.println(str);

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

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

	//--------------------------------------------------------------------
	//类名 :: 静态方法名
	@Test
	public void test3(){
		Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
		int compare1 = com.compare(12,21); //-1
		System.out.println(compare1);
		/*点击compare进去发现是静态的方法:
		public static int compare(int x, int y) {
			return (x < y) ? -1 : ((x == y) ? 0 : 1);
		}
		返回值int
		参数列表int x, int y

		函数式接口抽象方法的返回值和列表
		int compare(T o1, T o2);
		*/

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

		Comparator<Integer> com2 = Integer::compare;
		int compare2 = com2.compare(12,21); //-1
		System.out.println(compare2);
	}


	//--------------------------------------------------------------------
	//类名 :: 实例方法名
	@Test
	public void test4(){
		BiPredicate<String, String> bp = (x, y) -> x.equals(y);
		System.out.println(bp.test("abcde", "abcde"));

		//若Lambda的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
		//(x, y) -> x.equals(y)
		BiPredicate<String, String> bp2 = String::equals;
		System.out.println(bp2.test("abc", "abc"));

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


		Function<Employee, String> fun = (e) -> e.show();
		System.out.println(fun.apply(new Employee()));

		Function<Employee, String> fun2 = Employee::show;
		System.out.println(fun2.apply(new Employee()));

	}

	@Test
	public void test5(){
		BiFunction<Double, Double, Double> fun = (x, y) -> Math.max(x, y);
		System.out.println(fun.apply(1.5, 22.2));

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

		BiFunction<Double, Double, Double> fun2 = Math::max;
		System.out.println(fun2.apply(1.2, 1.5));
	}

	//--------------------------------------------------------------------
	//构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!
	@Test
	public void test6(){
		Supplier<Employee> sup = () -> new Employee();
		System.out.println(sup.get());//Employee{name='null', age=0, salary=0.0}

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

		Supplier<Employee> sup2 = Employee::new; //匹配无参构造器
		Employee emp = sup2.get();//返回一个对象
		System.out.println(emp);//Employee{name='null', age=0, salary=0.0}
	}

	@Test
	public void test7(){
		Function<Integer, Employee> fun = (x) -> new Employee();//匹配一个参数的构造器

		Function<Integer, Employee> fun2 = Employee :: new;//匹配一个参数的构造器
		Employee emp = fun2.apply(1000);
		System.out.println(emp);

		//传两个参数,必须要有两个参数的构造器
		BiFunction<String, Integer, Employee> fun3 = Employee::new;//匹配两个参数的构造器
	}

	//--------------------------------------------------------------------

	//数组引用
	@Test
	public void test8(){
		Function<Integer, String[]> fun = (args) -> new String[args];
		String[] strs = fun.apply(10);
		System.out.println(strs.length);//数组长度为10
		
		System.out.println("--------------------------");
		
		Function<Integer, Employee[]> fun2 = Employee[] :: new;
		Employee[] emps = fun2.apply(20);
		System.out.println(emps.length);//数组长度为20
	}
	

	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值