zoukankan      html  css  js  c++  java
  • 廖雪峰Java16函数式编程-1Lambda表达式-3方法引用

    Java8引入了Lambda表达式,可以不必编写FunctionalInterface的实现类,直接写Lambda表达式。除了Lambda表达式,我们还可以直接传入方法引用

    方法引用是指:如果某个方法签名和接口恰好一致,可以直接传入方法引用,格式:类名::方法名

    静态方法引用

    在SortedBy这个类中定义了一个静态方法,其方法签名是传入2个String,返回int。

    class SortedBy{
        static int nameIgnoreCase(String s1, String s2){
            return s1.toLowerCase.compareTo(s2.toLowerCase());
        }                                                                                 
    }
    

    此时和范型的Comparator接口比较,这2个方法签名是一致的。

    注意:这里的方法签名只看方法类型和返回值类型。

    ```#java interface Comparator{ int compare(String s1, String s2); } ``` ignoreCase恰好符合Comparator的接口定义。因此在需要传入Comparator的地方,我们直接传入方法引用 ```#java public static void main(String[] args){ String[] array = "Java Apple lambda functional OOP".split(" "); Arrays.sort(array,SortedBy::nameIgnoreCase); System.out.println(Arrays.toString(array)); } ```

    实例方法引用

    public class String{
        public int compareToIgnoreCase(String s){
        ...
        }
    }
    

    String的compareToIgnoreCase参数是String,返回值是int,看上去并不符合Comparator接口的定义。
    但是实例方法调用时,必须有一个隐含的实例变量。即调用String类的compareToIgnoreCase必须有一个String类型的实例,实例参数+方法参数就通Comparator接口定义是一致的。
    注意:隐含的this实例变量是方法的第一个参数。

    Arrays.sort(array, String::compareToIgnoreCase);
        //=>instance.compareToIgnoreCase(s) 
        //=> Comparator.compare(instance, s) 
    

    构造方法引用

    class Person{
        String name;
        public Person(String name){
            this.name = name;
        }
    }
    

    把一个String类型的List转化为Person类型的List?
    方法1:先定义一个ArrayList,然后用for循环来填充这个List。

        List<String> names = Arrays.asList("Bob", "Alice", "Tim");
        List<Person> person = new ArrayList<>();
        for(String name: names){
            Person p = new Person(name);
            persons.add(p);
        }
    

    方法2:直接引用Person类的构造方法,不用手动创建Person实例
    map()传入的方法签名:参数为String,返回值为Person对象。编译器自动查找符合条件的构造方法
    构造方法的引用为:类名::new
    虽然Java构造方法内部不能持有return语句,但构造方法是有返回值的,它的返回值是this,即当前实例。

        List<String> names = Arrays.asList("Bob", "Alice", "Tim");
        List<Person> persons = names.stream().map(Person::new).collect(collectors.toList());
    
    import java.util.Arrays;
    
    class SortedBy {
        static int name(String s1, String s2) {
            return s1.compareTo(s2);
        }
    
        static int nameIgnoreCase(String s1, String s2) {
            return s1.toLowerCase().compareTo(s2.toLowerCase());
        }
    
        static int length(String s1, String s2){
            int n1 = s1.length();
            int n2 = s2.length();
            if(n1==n2){
                return s1.compareTo(s2);
            }
            return n1 < n2 ? -1:1;
        }
    }
    public class LambdaSort {
        public static void main(String[] args){
            String[] array = "Java Apple lambda functional OOP".split(" ");
            Arrays.sort(array,SortedBy::nameIgnoreCase);
            System.out.println(Arrays.toString(array));
        }
    }
    

    总结

    Functional Interface可以传入:

    • 接口的实现类(代码较繁琐)
    • Lambda表达式
    • 符合方法签名的静态方法
    • 符合方法签名的实例方法(实例类型被看作第一个参数类型)
    • 符合方法签名的构造方法(实例类型被看作返回类型)
  • 相关阅读:
    linux基础练习题(3)
    linux基础练习题(2)
    linux基础练习题(1)
    编辑器 vim
    Linux 命令总结
    Sublime Text 3 快捷键总结(拿走)
    Linux 主要目录速查表
    javaScript中的querySelector()与querySelectorAll()的区别
    javaScript定时器
    js基本类型和字符串的具体应用
  • 原文地址:https://www.cnblogs.com/csj2018/p/11469816.html
Copyright © 2011-2022 走看看