我们使用lambda表达式创建了一个匿名函数,也就是利用lambda表达式来直接指定函数要实现的功能,但是有时候lambda表达式并不做任何事情,而只是调用一个现有的方法,例如下面这个对对象型数组进行排序的例子:

public class Main {
    public static void main(String[] args) {
        Person[] pers = {new Person(12, "h1"),
                new Person(23, "h2"),
                new Person(14, "h3"),
                new Person(2, "h4")};
        Arrays.sort(pers,(a,b)->{return a.getAge()-b.getAge();});
        Arrays.stream(pers).forEach(obj -> System.out.print(obj + " "));

    }
}
@Data
@ToString
class Person{
    int age;
    String name;
    public Person(int age,String name){
        this.age=age;
        this.name=name;
    }
    public static int compareByAge(Person a,Person b){
        return a.age-b.age;
    }
}

上一节已经总结了,Arrays.sort的参数是T[] a, Comparator<? super T> c,其中Comparator是一个函数式接口,可用lambda表达式指定其实现结构:(a,b)->{return a.getAge()-b.getAge();},但是这个方法实现已经在Person中定义了,也就是compareByAge方法,所以我们的排序也可以这样指定:

public class Main {
    public static void main(String[] args) {
        Person[] pers = {new Person(12, "h1"),
                new Person(23, "h2"),
                new Person(14, "h3"),
                new Person(2, "h4")};
        Arrays.sort(pers,(a,b)->Person.compareByAge(a,b));
        Arrays.stream(pers).forEach(obj -> System.out.print(obj + " "));

    }
}

 上面的lambda表达式触发一个已经存在的方法,所以也可以使用方法引用(method reference)的形式来代替lambda表达式:

Arrays.sort(pers,Person::compareByAge);

上面的语法形式就是方法引用,有四种形式的方法引用,如下图:

  下面的代码将前三种类型的方法引用展示了出来:

public class MethodReferenceExample {

    public static <T> T mergeThings(T a, T b, BiFunction<T,T,T> merger){
        return merger.apply(a,b);
    }
    public static String appendString(String a,String b){
        return a+b;
    }
    public String appendString2(String a,String b){
        return a+b;
    }
    public static void main(String[] args) {
        MethodReferenceExample methodReferenceExample=new MethodReferenceExample();
        //利用lambda表达式实现功能
        System.out.println(MethodReferenceExample.mergeThings("ab","cd",(a,b)->a+b));
        //利用静态方法引用实现功能
        System.out.println(MethodReferenceExample.mergeThings("ab","cd",MethodReferenceExample::appendString));
        //利用实例方法引用实现功能
        System.out.println(MethodReferenceExample.mergeThings("ab","cd",methodReferenceExample::appendString2));
        //利用对象所属类型的实例方法引用实现功能,下面的待合并的对象都是字符串,可引用String的实例方法concat实现功能
        System.out.println(MethodReferenceExample.mergeThings("ab","cd",String::concat));
    }
}

又如:

 String[] strArray={"Barbara","James","Mary","John","Patricia","Robert","Michael","Linda"};

Arrays.sort(strArray,String::compareToIgnoreCase);

构造方法引用实例如下: 

 public static <T,SOURCE extends Collection<T>,DEST extends Collection<T>> DEST transferElements(SOURCE src, Supplier<DEST> des){
        DEST result=des.get();
        for(T t:src){
            result.add(t);
        }
        return result;
    }

    public static void main(String[] args) {
        String[] strArray={"Barbara","James","Mary","John","Patricia","Robert","Michael","Linda"};
        List<String> src= Arrays.asList(strArray);
        //使用lambda表达式创建ArrayList对象
        List<String> res2= transferElements(src, ()-> new ArrayList<>());
        //使用构造方法引用创建ArrayList对象
        List<String> res1= transferElements(src, ArrayList::new);
    }

 

上面的代码使用构造方法引用创建ArrayList对象,有了方法引用,Lambda表达式的使用更为简练了 

posted on 2022-01-27 14:01  Judy518  阅读(40)  评论(0编辑  收藏  举报