Java新特性--方法引用
常见方法引用
方法引用可以让你重复使用现有的方法定义,并像Lambda
一样传递它们。
方法引用可以看做是仅仅调用特定方法的Lambda
表达式的一种便捷写法。类似于Lambda
表达式,方法引用不能独立存在,总是会转换为函数式接口的实例。
需要使用方法引用时,用::
操作符分隔对象(或类名)和方法名,目标引用放在分隔符::
前面,方法名放在::
后面。
注意,只需要方法名,不需要小括号。
主要有三种情况:
对象::实例方法
Class::静态方法
Class::实例方法
指向静态方法的方法引用
Lambda表达式:(args) -> ClassName.staticMethod(args)
方法引用:ClassName::staticMethod
实例一:
@Test public void test02(){ Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y); System.out.println(com1.compare(1, 2)); Comparator<Integer> com2 = Integer::compare; System.out.println(com2.compare(2, 1)); }
示例二:
Integer[] data = {21,90,34,76}; Arrays.sort(data, Integer::compare);//引用静态方法 System.out.println(Arrays.toString(data));
其中Arrays.sort方法解释
static <T> void sort(T[] a, Comparator<? super T> c) 根据指定的比较器引发的顺序对指定的对象数组进行排序。
指向任意类型的实例方法的引用
Lambda表达式:
(args0, args1) -> args0.instanceMethod(args1)
args0
是ClassName
类型的一个对象
方法引用:ClassName::instanceMethod
Lambda 参数列表中的第一个参数是方法的调用者,第二个参数是方法的参数时(或不存在时,例如调用JavaBean的get()方法),才能使用 ClassName :: Method
示例一:
@Test public void test03(){ BiPredicate<String, String> bp1 = (x, y) -> x.equals(y); System.out.println(bp1.test("a","b")); BiPredicate<String, String> bp2 = String::equals; System.out.println(bp2.test("c","c")); }
其中Predicate的test方法解释
boolean test(T t, U u) 根据给定的参数来评估这个谓词。
实例二:
List<String> list = Arrays.asList("ccc", "bbb", "aaa"); list.sort(String::compareTo);//引用实例方法 System.out.println(list);
其中list.sort方法解释:
default void sort(Comparator<? super E> c) 使用随附的 Comparator排序此列表来比较元素。
指向现有对象的实例方法的引用
Lambda表达式:(args) -> obj.instanceMethod(args)
方法引用:obj::instanceMethod
示例一:
@Test public void test01(){ PrintStream ps = System.out; Consumer<String> con1 = (s) -> ps.println(s); con1.accept("aaa"); Consumer<String> con2 = ps::println; con2.accept("bbb"); }
示例二:
list.forEach(System.out::println);
构造方法引用
对于一个现有的构造方法,可以使用类名和关键字new
来创建一个构造方法的引用:ClassName::new
package com.wangbo.cto.lambda; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; /** * @date 2019/11/14 23:08 * @auther wangbo */ public class Test1 { public static void main(String[] args) { //引用无参数构造方法 Supplier<Person> supplier = Person::new; Person p1 = supplier.get(); System.out.println(p1); //引用有一个参数构造方法 Function<String, Person> function = Person::new; Person p2 = function.apply("wangbo"); System.out.println(p2); //应用有两个参数的构造方法 BiFunction<String, Integer, Person> biFunction = Person::new; Person p3 = biFunction.apply("wangbo", 28); System.out.println(p3); //如果引用有三个参数及三个以上参数的构造方法,需要自定义匹配的函数式接口 TriFunction<String, Integer, String, Person> triFunction = Person::new; Person p4 = triFunction.myMethod("zhangsan", 90, "男"); System.out.println(p4); } }
/** * 自定义函数式接口 */ @FunctionalInterface public interface TriFunction<T, U, V, R>{ R myMethod(T t, U u, V v); }
public class Person{ String name; Integer age; String gender; public Person(){} public Person(String name) { this.name = name; } public Person(String name, Integer age) { this.name = name; this.age = age; } public Person(String name, Integer age, String gender) { this.name = name; this.age = age; this.gender = gender; } @Override public String toString() { return "Person{" + "name=" + name + ", age=" + age + ", gender="+ gender + "}"; } }
运行结果
Person{name=null, age=null, gender=null} Person{name=wangbo, age=null, gender=null} Person{name=wangbo, age=28, gender=null} Person{name=zhangsan, age=90, gender=男}