方法引用
方法引用(Method References)
- 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用! 
- 方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就 是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。 
- 要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致(参数个数不要求)! 
- 格式:使用操作符 “- ::” 将类(或对象) 与 方法名分隔开来。
 
如下三种主要使用情况:
- 对象::实例方法名 
- 类::静态方法名 
- 类::实例方法名

方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同!(针对于情况1和情况2)
对象::实例方法名

| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | 
 
 @Test
 public void test1() {
 
 Consumer<String> consumer = new Consumer<String>() {
 @Override
 public void accept(String str) {
 System.out.println(str);
 }
 };
 consumer.accept("世界");
 
 
 Consumer con1 = str -> System.out.println(str);
 con1.accept("你好");
 
 
 PrintStream printStream = System.out;
 Consumer tConsumer1 = printStream::println;
 tConsumer1.accept("世界你好");
 
 Consumer tConsumer = System.out::print;
 tConsumer.accept("你好世界");
 }
 
 | 


| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | 
 @Test
 public void test2() {
 Employee common = new Employee(10000, "common", 1, 0);
 Supplier<String> s1 = new Supplier<String>() {
 @Override
 public String get() {
 return common.getName();
 }
 };
 System.out.println(s1.get());
 
 
 Employee kylin = new Employee(10001, "kylin", 11, 1111);
 Supplier<String> s2 = () -> kylin.getName();
 System.out.println(s2.get());
 
 
 Employee mr = new Employee(10001, "MethodRef", 7, 9999);
 Supplier<String> s3 = mr::getName;
 System.out.println(s3.get());
 }
 
 | 
类::静态方法

| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 | 
 
 @Test
 public void test3() {
 
 Comparator<Integer> c1 = new Comparator<Integer>() {
 @Override
 public int compare(Integer t1, Integer t2) {
 
 return Integer.compare(t1, t2);
 }
 };
 System.out.println(c1.compare(12, 21));
 
 
 Comparator<Integer> c2 = (t1, t2) -> Integer.compare(t1, t2);
 System.out.println(c2.compare(12, 21));
 
 
 
 Comparator<Integer> c3 = Integer::compare;
 System.out.println(c3.compare(12, 21));
 }
 
 | 


| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | 
 @Test
 public void test4() {
 
 Function<Double, Long> function1 = new Function<Double, Long>() {
 
 @Override
 public Long apply(Double d) {
 return Math.round(d);
 }
 };
 System.out.println(function1.apply(5.3));
 
 
 Function<Double, Long> function2 = (d) -> Math.round(d);
 System.out.println(function2.apply(5.4));
 
 
 Function<Double, Long> function3 = Math::round;
 System.out.println(function3.apply(5.5));
 }
 
 | 

类::实例方法

| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 
 | 
 
 @Test
 public void test5() {
 
 Comparator<String> c1 = new Comparator<String>() {
 @Override
 public int compare(String s1, String s2) {
 return s1.compareTo(s2);
 }
 };
 
 System.out.println(c1.compare("1", "4"));
 
 Comparator<String> c2 = (s1, s2) -> s1.compareTo(s2);
 System.out.println(c2.compare("3", "7"));
 
 
 Comparator<String> c3 = String::compareTo;
 System.out.println(c3.compare("9", "1"));
 
 }
 
 | 


| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | 
 @Test
 public void test6() {
 
 BiPredicate<String, String> b1 = new BiPredicate<String, String>() {
 @Override
 public boolean test(String s1, String s2) {
 return s1.equals(s2);
 }
 };
 System.out.println(b1.test("a", "a"));
 
 
 BiPredicate<String, String> b2 = (s1, s2) -> s1.equals(s2);
 System.out.println(b2.test("c", "a"));
 
 
 BiPredicate<String, String> b3 = String::equals;
 System.out.println(b3.test("e", "e"));
 }
 
 | 

结论
其中就是方法引用可以看做是Lambda表达式深层次的表达。使用方法引用必须保证该方法能和某一个对应的函数接口的方法返回值,参数类型保持一致。如果参数个数不一样例如
如果想不到使用方法引用,则可以退而求其次使用lambda表达式,或者使用最普通的方式。这只是一种语法而已。只要求能看懂如果有相关源码中使用该语法能知晓真实意图做了啥即可。