**资本的情怀不如钱实在!见人说人话,见鬼说鬼话!**
一、什么是方法引用?
方法引用是Lambda表达式的一种简写形式。 如果Lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用。(有点抽象)Lambda表达式可以理解为特殊的匿名内部类的一种简写方式,而方法引用可以理解为Lambda表达式的进一步简化。
二、常见形式
1、对象::实例方法
2、类::静态方法
3、类::实例方法
4、类::new 也叫 构造器引用
方法引用的使用
- 1、使用场景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
- 2、方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用,也是函数式接口的实例
- 3、使用格式:类(或对象)::方法名
- 4、具体分为如下三种情况:
- (情况1)对象::非静态方法
- (情况2)类::静态方法
- (情况3)类::非静态方法
- 5、方法引用使用的要求:(针对 情况1 和 情况2)
要求:接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!
1.方法引用的使用
package com.csqf.jdk8.d_demo;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 方法引用
* 常见形式
1、对象::实例方法
说明:如果Lambda表达式中只调用了一个方法,比如:println(),并且这个方法的特点
和接口方法void accept(T t)的特点是一样的,比如 有一个参数,没有返回值,那么这种情况下可以使用方法引用。
Consumer中的void accept(T t)
PrintStream中的void println(T t)
2、类::静态方法
3、类::实例方法
4、类::new
* @author Administrator
* @date 2020年7月12日
*/
public class Demo8 {
public static void main(String[] args) {
//1、对象::实例方法 特点:1个参数,无返回值
Consumer<String> consumer = s->System.out.println(s);
consumer.accept("hello");
//方法引用 更简洁的写法
Consumer<String> consumer2 = System.out::println;
consumer2.accept("world");
//2、类::静态方法 特点:2个参数,1个返回值
Comparator<Integer> com = (o1,o2) -> Integer.compare(o1,o2);
//方法引用 更简洁的写法
Comparator<Integer> com2 = Integer::compare;
int result = com2.compare(55, 66);
System.out.println(result);
//3、类::实例方法 Employee类 和 getName()方法
// 特点:方法的调用者对象Employee,正好是我传进来的参数Employee
//并且方法的返回值与接口方法的返回值是一样的
Function<Employee,String> function = e->e.getName();
//方法引用 更简洁的写法
Function<Employee,String> function2 = Employee::getName;
String result2 = function2.apply(new Employee("lucy",5000));
System.out.println(result2);
//4、类::new 创建对象 构造器引用 方法体只有一个创建对象语句
Supplier<Employee> supplier = ()->new Employee();
//方法引用 更简洁的写法
Supplier<Employee> supplier2 = Employee::new;
Employee emp = supplier.get();
System.out.println(emp);
Employee emp2 = supplier2.get();
System.out.println(emp2);
}
}
public class Employee {
private String name;
private double money;
public Employee() {
super();
}
public Employee(String name, double money) {
super();
this.name = name;
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Employee [name=" + name + ", money=" + money + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(money);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (Double.doubleToLongBits(money) != Double.doubleToLongBits(other.money))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
package com.enbo.jdk8.demo3;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
/**
* 方法引用的使用
* 1、使用场景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。
* 2、方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例,所以方法引用,也是函数式接口的实例
* 3、使用格式:类(或对象)::方法名
* 4、具体分为如下三种情况:
* (情况1)对象::非静态方法
* (情况2)类::静态方法
* (情况3)类::非静态方法
* 5、方法引用使用的要求:(针对 情况1 和 情况2)
* 要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!
* @author Administrator
* @date 2020年5月22日
*/
public class MethodRefTest {
//情况1:对象::示例方法
//Consumer中的void accept(T t)
//PrintStream中的void println(T t)
@Test
public void test1(){
Consumer<String> con1 = str -> System.out.println(str);
con1.accept("长沙");
System.out.println("---------------------");
//方法引用 更简洁的写法
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("changsha");
}
//Supplier 中的 T get()
//Employee 中的String getName()
@Test
public void test2(){
Employee emp = new Employee(1001,"lucy",22,8800);
Supplier<String> sup1 = () -> emp.getName();
System.out.println(sup1.get());
System.out.println("---------------------");
//方法引用 更简洁的写法
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());
}
//情况2:类::静态方法
//Comparator中的 int compare(T t1,T t2)
//Integer中的int compare(T t1,T t2)
@Test
public void test3(){
Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1, t2);
System.out.println(com1.compare(12, 22));
System.out.println("---------------------");
//方法引用 更简洁的写法
Comparator<Integer> com2 = Integer :: compare;
System.out.println(com2.compare(112, 22));
}
//Function中的R apply(T t)
//Math中的Long round(Double d)
@Test
public void test4(){
//原来的写法
Function<Double,Long> func0 = new Function<Double,Long>(){
@Override
public Long apply(Double d) {
return Math.round(d);
}
};
System.out.println(func0.apply(11.3));
System.out.println("---------------------");
Function<Double,Long> func1 = d -> Math.round(d);
System.out.println(func1.apply(12.3));
System.out.println("---------------------");
//方法引用 更简洁的写法
Function<Double,Long> func2 = Math :: round;
System.out.println(func2.apply(12.6));
}
//情况3:类::实例方法 (有点难度)
//Comparator中的 int compare(T t1,T t2)
//String中的int t1.compareTo(t2)
@Test
public void test5(){
Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
System.out.println(com1.compare("abc", "abd"));
System.out.println("---------------------");
//方法引用 更简洁的写法
Comparator<String> com2 = String :: compareTo;
System.out.println(com2.compare("abd", "abm"));
}
//BiPredicate中的boolean test(T t1,T t2);
//String中的boolean t1.equals(t2);
@Test
public void test6(){
BiPredicate<String,String> pre1 = (s1,s2) -> s1.equals(s2);
System.out.println(pre1.test("abc", "abc"));
System.out.println("---------------------");
//方法引用 更简洁的写法
BiPredicate<String,String> pre2 = String :: equals;
System.out.println(pre2.test("abc", "abd"));
}
//Functiion中的R apply(T t)
//Employee中的String getName()
@Test
public void test7(){
Employee emp = new Employee(1001,"lucy",22,8800);
Function<Employee,String> func1 = e -> e.getName();
System.out.println(func1.apply(emp));
System.out.println("---------------------");
//方法引用 更简洁的写法
Function<Employee,String> func2 = Employee :: getName;
System.out.println(func2.apply(emp));
}
2.构造器引用与数组引用的使用
package com.enbo.jdk8.demo3;
import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
/**
* 一、构造器引用
* 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致,
* 抽象方法的返回值类型即为构造器所属的类的类型
*
* 二、数组引用
* 可以把数组看做是一个特殊的类,则写法与构造器引用一致
*
* @author Administrator
* @date 2020年5月22日
*/
public class ConstructorRefTest {
//构造器引用
//Supplier中的 T get()
//Employee 的空参构造器:Employee()
@Test
public void test1(){
Supplier<Employee> sup = new Supplier<Employee>(){
@Override
public Employee get() {
return new Employee();
}
};
System.out.println(" ---------------------- ");
Supplier<Employee> sup1 = () -> new Employee();
System.out.println(sup1.get());
System.out.println(" ---------构造器引用------------- ");
//方法引用 更简洁的写法
Supplier<Employee> sup3 = Employee :: new;
System.out.println(sup3.get());
}
//Function中的R apply(T t)
@Test
public void test2(){
Function<Integer,Employee> func1 = id -> new Employee(id);
Employee employee = func1.apply(1001);
System.out.println(employee);
System.out.println(" ---------------------- ");
//方法引用 更简洁的写法
Function<Integer,Employee> func2 = Employee::new;
Employee employee2 = func2.apply(1002);
System.out.println(employee2);
}
//BiFunction中的R apply(T t,U u)
@Test
public void test3(){
BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);
System.out.println(func1.apply(1001, "lucy"));
System.out.println(" ---------------------- ");
//方法引用 更简洁的写法
BiFunction<Integer,String,Employee> func2 = Employee :: new;
System.out.println(func2.apply(1002, "mark"));
}
//数组引用
//Function中的R apply(T t)
@Test
public void test4(){
Function<Integer,String[]> func1 = length -> new String[length];
String[] arr1 = func1.apply(5);
System.out.println(Arrays.toString(arr1));
System.out.println(" ---------------------- ");
//方法引用 更简洁的写法
Function<Integer,String[]> func2 = String[] :: new;
String[] arr2 = func2.apply(10);
System.out.println(Arrays.toString(arr2));
}
}