JAVA 8 新特性 方法引用

摘自b站尚硅谷JAVA视频教程

 

    方法引用 ,形式有三种: 1、实例::实例方法名     2、 类名::静态方法名     3、类名::实例方法名
    构造器引用 ,形式有一种: 类名::new
    数组引用  ,形式有一种:类型[]::new

准备:定义一个person类,字段如下:

    public class Person {
        private String name;
        private int age;
        public Person(String name) {
            this.name = name;
        }
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        //省略get/set方法...
    }

 


1. 实例::实例方法名

    public void test1(){
        Person person=new Person("小明",18);
     
        Supplier<String> supplier=()->person.getName();
        System.out.println(supplier.get());
        
        //上面lambda体只用到person实例的getName()方法,因此可以改写成实例::实例方法名
        Supplier<String> supplier1=person::getName;
        System.out.println(supplier1.get());
    }

 



2. 类名::静态方法名

    public void test2(){
        //普通lambda方式
        Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
     
        //类名:静态方法名
        Comparator<Integer> com2 = Integer::compare;
    }

 



3. 类名::实例方法名,前提:Lambda 参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数。

    public void test3() {
        String[] strArray = {"a", "c", "b"};
        Arrays.sort(strArray, (s1, s2) -> s1.compareTo(s2));
     
        //lambda的第一个参数s1 是实例方法compareTo()的调用者
        //且lambda的第二个参数s2 是compareTo()的参数
        Arrays.sort(strArray, String::compareTo);
    }

 



4. 类名::new ,前提:构造器的参数列表,需要与函数式接口中参数列表保持一致

    public void test4(){
        // Function的参数为String,匹配 public Person(String name)
        Function<String, Person> fun = Person::new;
     
        //BiFunction的参数为String,Integer,匹配 public Person(String name, int age)
        BiFunction<String, Integer, Person> fun2 = Person::new;
    }

 



5. 类型[]::new

    public void test5() {
        Function<Integer, String[]> fun = (length) -> new String[length];
        String[] strs1 = fun.apply(10);
        System.out.println(strs1.length);
     
        System.out.println("--------------------------");
     
        Function<Integer, String[]> fun2 = String[]::new;
        String[] strs2 = fun2.apply(20);
        System.out.println(strs2.length);
    }

 



6. 补充:

6.1. 当lambda体调用的方法是父类中的方法或者是当前类中的方法时,可以使用 super::实例方法名 或 this::实例方法名

   

public class Father {
        public int add(int a, int b) {
            return a + b;
        }
    }
     
    public class Son extends Father {
        public int add(int a, int b) {
            return a + b + 2;
        }
     
        public int calculate(BiFunction<Integer, Integer, Integer> function, int a, int b) {
            return function.apply(a, b);
        }
     
        @Test
        public void test() {
            int fatherAdd = calculate(super::add, 1, 2);
            int sonAdd = calculate(this::add, 1, 2);
            System.out.println(fatherAdd);
            System.out.println(sonAdd);
        }
    }
     
    //运行结果:
    3
    5

 



6.2  当lambda体中的方法有泛型是,可以在双冒号:: 之后指定类型。

  

 public interface MyFunc<T> {
        int func(T[] als, T v);
    }
     
    public class MyArrayOps {
        //统计v在数组中出现的次数
        public static <T> int countMatching(T[] array, T v) {
            int count = 0;
            for (T t : array) {
                if (t.equals(v)) count++;
            }
            return count;
        }
    }
     
    public class Run {
     
        public static <T> int myOp(MyFunc<T> f, T[] array, T v) {
            return f.func(array, v);
        }
     
        public static void main(String[] args) {
            Integer[] vals = {1, 2, 3, 4, 2, 3, 4, 4, 5};
            String[] strs = {"One", "Two", "Three", "Two"};
     
            //不指定MyFunc类型时,可根据后面的参数推断
            int count1 = myOp(MyArrayOps::countMatching, vals, 4);
            System.out.println("vals contains " + count1 + " 4s");
     
            //要指定类型时,可以在::后面指定,指定完可以限制后面两个参数的类型
            int count2 = myOp(MyArrayOps::<String>countMatching, strs, "Two");
            System.out.println("strs contains " + count2 + " Twos");
        }
    }

 



原文链接

posted @ 2020-02-25 15:28  超级学渣渣  阅读(217)  评论(0编辑  收藏  举报