美文网首页
Java lambda表达式

Java lambda表达式

作者: 小元与大坝 | 来源:发表于2017-08-01 11:45 被阅读0次

    1. Java函数式接口

    Java实现函数式编程的方式是函数式接口(functional interface),函数式接口简单来说,是只包含一个抽象方法的接口。比如Java标准库中的java.lang.Runnable和 java.util.Comparator都是典型的函数式接口。
    java 8提供 @FunctionalInterface作为函数式接口的注解,该注解非强制使用,主要防止团队的其他人员错误地往接口中添加新的方法。

    2. lambda表达式

    lambda表达式是匿名方法,是函数式接口的匿名实现。
    使用lambda表达式实现Runnable例子:

    // 使用匿名内部类  
    new Thread(new Runnable() {  
        public void run() {  
            System.out.println("Hello world !");  
        }  
    }).start();    
    // 使用 lambda 表达式
    new Thread(() -> System.out.println("Hello world !")).start();
    

    3. lambda语法

    (parameters) -> expression
    或者
    (parameters) -> { statements; }

    JButton jb=new JButton();
    jb.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("press button");
        }
    });
    jb.addActionListener((ActionEvent e)->{System.out.println("press button");});
    jb.addActionListener((e)->{System.out.println("press button");});
    jb.addActionListener((x)->System.out.println("press button"));
    jb.addActionListener(x->System.out.println("press button"));
    

    为了更好的支持lambda,Java8引入了一个新包java.util.function,它里面包含了常用的函数式接口,例如:

    Predicate<T>——接收T对象并返回boolean
    Consumer<T>——接收T对象,不返回值
    Function<T, R>——接收T对象,返回R对象
    Supplier<T>——提供T对象(例如工厂),不接收值
    UnaryOperator<T>——接收T对象,返回T对象
    BinaryOperator<T>——接收两个T对象,返回T对象

    在参数为这些接口的地方,我们就可以直接使用lambda表达式了!

    4. 方法引用(Method references)

    lambda表达式允许我们定义一个匿名方法,并允许我们以函数式接口的方式使用它。我们也希望能够在已有的方法上实现同样的特性。

    方法引用和lambda表达式拥有相同的特性(例如,它们都需要一个目标类型,并需要被转化为函数式接口的实例),不过我们并不需要为方法引用提供方法体,我们可以直接通过方法名称引用已有方法。
    以下面的代码为例,假设我们要按照name为Person数组进行排序:

    class Person {
      private final String name;
      private final int age;
    
      public int getAge() { return age; }
      public String getName() {return name; }
      ...
    }
    
    Person[] people = ...
    Comparator<Person> byName = Comparator.comparing(p -> p.getName());
    Arrays.sort(people, byName);
    

    在这里我们可以用方法引用代替lambda表达式:

    Comparator<Person> byName = Comparator.comparing(Person::getName);
    

    方法引用的形式
    方法引用的标准形式是:类名::方法名。(注意:只需要写方法名,不需要写括号)

    有以下四种形式的方法引用:

    引用静态方法
    引用某个对象的实例方法
    引用某个类型的任意对象的实例方法
    引用构造方法

    • 引用静态方法
      ContainingClass::staticMethodName
      例子: String::valueOf,对应的Lambda:(s) -> String.valueOf(s)
      比较容易理解,和静态方法调用相比,只是把.换为::
    • 引用特定对象的实例方法
      containingObject::instanceMethodName
      例子: x::toString,对应的Lambda:() -> this.toString()
      与引用静态方法相比,都换为实例的而已
    • 引用特定类型的任意对象的实例方法
      ContainingType::methodName
      例子: String::toString,对应的Lambda:(s) -> s.toString()
      实例方法要通过对象来调用,方法引用对应Lambda,Lambda的第一个参数会成为调用实例方法的对象。
    • 引用构造函数
      ClassName::new
      例子: String::new,对应的Lambda:() -> new String()
      构造函数本质上是静态方法,只是方法名字比较特殊。

    写个例子帮本节内容串一下帮助理解:

    class Person {
        Integer age;
        public static int compareByAge(Person a,Person b){return a.age.compareTo(b.age);}
        public int compareByAge2(Person b){return age.compareTo(b.age);}
    
        public static int compareBy18(Person p){return p.age.compareTo(18);}
        public int compareBy14(){return age.compareTo(14);}
    }
    public void sort(){
        Person [] persons=new Person[10];
        //使用匿名类
        Arrays.sort(persons, new Comparator<Person>() {
                    public int compare(Person o1, Person o2) {
                        return o1.age.compareTo(o2.age);
                    }
         });
        //使用lambda表达式
        Arrays.sort(persons, (o1, o2) -> o1.age.compareTo(o2.age));
        //使用lambda表达式和类的静态方法
        Arrays.sort(persons, (o1, o2) -> Person.compareByAge(o1,o2));
        //使用lambda表达式和实例方法
        Arrays.sort(persons, (o1, o2) -> o1.compareByAge2(o2));
    
        //使用方法引用
        //引用的是类的静态方法
        Arrays.sort(persons, Person::compareByAge);
        //引用特定类型的任意对象的实例方法
        Arrays.sort(persons, Person::compareByAge2);
        //引用的是类的静态方法
        Arrays.sort(persons,Comparator.comparing(Person::compareBy18));
        //引用特定类型的任意对象的实例方法
        Arrays.sort(persons,Comparator.comparing(Person::compareBy14));
    }
    

    `

    相关文章

      网友评论

          本文标题:Java lambda表达式

          本文链接:https://www.haomeiwen.com/subject/hcwllxtx.html