项目中用到的 JDK 7、JDK 8 的新特性(2)Lambda 表达式

此系列博文用于向我的同事介绍我在新项目中使用了一些 Java SE 1.7、Java SE 1.8 的新特性,以便同事阅读和维护这些代码。

2、Lambda表达式

从 JDK 8 开始,Java 中引入了一个 FunctionalInterface 的概念。FunctionalInterface 即只定义了一个(非 default)方法的接口,例如:

public interface Runnable {
    void run();
}
public interface Callable<V> {
    V call();
}
public interface Consumer<T> {
    void accept(T t);
}
public interface BiConsumer<T, U> {
    void accept(T t, U u);
}

等等。而 Lambda 表达式可以让我们用更少的代码来实现 FunctionalInterface 的匿名类。

例如:

Thread thread = new Thread(new Runnable() {
    @Override public void run() {
        doSomething();
    }
}

可以用 Lambda 表达式写为:

Thread thread = new Thread(() -> {
    doSomething();
});

如果代码块里只有一行代码,还可以省略掉大括号

Thread thread = new Thread(() -> doSomething());

 

又例如:

Function<String, List<String>> function = new Function<>() {
    @Override public List<String> accept(String str) {
        list.add(str);
        return list;
    }
};

可以用 Lambda 表达式写为:

Function<String, List<String>> function = (str) -> {
    list.add(str);
    return list;
};

 

再例如:

Supplier<Set<String>> supplier = new Supplier<>() {
    @Override public Set<String> get() {
        return new HashSet<String>();
    }
};

可以用 Lambda 表达式写为:

Supplier<Set<String>> supplier = () -> {
    return new HashSet<String>();
};

由于代码块里只有一行代码,可以省略掉大括号和 return 关键字

Supplier<Set<String>> supplier = () -> new HashSet<String>();

如果 Lambda 表达式对应的 FunctionalInterface 的方法没有参数,而且方法体内直接调用一个类的无参构造方法来返回一个对象的话,还可以使用 Class::new 这样的语法进一步简化代码

Supplier<Set<String>> supplier = HashSet::new;

 

如果 Lambda 表达式的 Lambda 体也是通过调用一个对象的一个方法完成,而且调用方法的对象是 Lambda 表达式的参数列表中的第一个,而剩下的参数正好是给这个方法的实参,那么 Lambda 表达式可以简化为“类名::实例方法”的形式。这句话比较难理解,所以我们来看以下 3 个例子吧:

BiConsumer<List<String>, String> accumulator = (list, item) => list.add(item) ;
// List.add 方法作用于 Lambda 表达式的第一个参数 list
// List.add 方法的参数为 Lambda 表达式除了第一个参数以外的所有参数
// 以上 Lambda 表达式可简化为以下 Lambda 表达式
BiConsumer<List<String>, String> accumulator = List::add ;

BinaryOperator<List> combiner = (resultList, subList) => resultList.addAll(subList) ;
// List.addAll 方法作用于 Lambda 表达式的第一个参数 resultList
// List.addAll 方法的参数为 Lambda 表达式除了第一个参数以外的所有参数
// 以上 Lambda 表达式可简化为以下 Lambda 表达式
BinaryOperator<List> combiner = List::addAll ;

MyFunctionalInterface myFI = (str, beginIndex, endIndex) => str.substring(beginIndex, endIndex) ;
// String.substring 方法作用于 Lambda 表达式的第一个参数 str
// String.substring 方法的参数为 Lambda 表达式除了第一个参数以外的所有参数 beginIndex, endIndex
// 以上 Lambda 表达式可简化为以下 Lambda 表达式
MyFunctionalInterface myFI = String::substring

 

posted @ 2021-11-21 19:14  Firas  阅读(101)  评论(0编辑  收藏  举报