Java lambda表达式

2017-08-01  本文已影响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);

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

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

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

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

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));
}

`

上一篇下一篇

猜你喜欢

热点阅读