Java 8 最大的变化就是引入了 Lambda表达式,一种紧凑的、传递行为的方式。面向对象编程是对数据进行抽象,而函数式编程是对行为进行抽象。现实世界中,数据和行为并存,程序也是如此...

为什么引入函数表达式?

  • 1996 年 1 月,Java 1.0 发布,此后计算机编程领域发生了翻天覆地的变化。商业发展需要更复杂的应用,大多数程序都跑在功能强大的多核 CPU 的机器上。带有高效运行时编译器的 Java 虚拟机(JVM)的出现,使程序员将更多精力放在编写干净、易于维护的代码 上,而不是思考如何将每一个 CPU 时钟周期、每字节内存物尽其用。
  • 多核 CPU 的兴起成为了不容回避的事实。涉及锁的编程算法不但容易出错,而且耗费时 间。人们开发了 java.util.concurrent 包和很多第三方类库,试图将并发抽象化,帮助程序员写出在多核 CPU 上运行良好的程序。很可惜,到目前为止,我们的成果还远远不够。
  • 开发类库的程序员使用 Java 时,发现抽象级别还不够。处理大型数据集合就是个很好的例子,面对大型数据集合,Java 还欠缺高效的并行操作。开发者能够使用 Java 8 编写复杂的集合处理算法,只需要简单修改一个方法,就能让代码在多核 CPU 上高效运行。为了编写 这类处理批量数据的并行类库,需要在语言层面上修改现有的 Java:增加 Lambda 表达式。

我认为 Lambda 函数表达式能编写出简单、干净、易读的代码和提高Java在大型数据集合的并行计算能力。

引用值,而不是变量

String name = getUserName();
name = formatUserName(name);
button.addActionListener(event -> System.out.println("hi " + name));

Lambda 表达式引用的是值,而不是变量。如果你试图给该变量多次赋值,然后在 Lambda 表达式中引用它,编译器就会报错。

函数接口

函数接口是只有一个抽象方法的接口,用作 Lambda 表达式的类型。

接口 参数 返回类型 类型 示例
Predicate T boolean 断言型接口 这张唱片已经发行了吗
Consumer T void 消费型接口 输出一个值
Function T R 函数型接口 获得 Artist 对象的名字
Supplier None T 供给型接口 工厂方法
UnaryOperator T T 接口 逻辑非(!)
BinaryOperator (T,T) T 接口 求两个数的乘积(*)
  • Predicate
Predicate<Integer> atLeast = x -> x > 5;
System.out.println(atLeast.test(6));  // true

public static List<String> filter(List<String> fruit, Predicate<String> predicate){
    List<String> f = new ArrayList<>();
    for (String s : fruit) {
        if(predicate.test(s)){
            f.add(s);
        }
    }
    return f;
}
public static void main(String[] args) {
    List<String> fruit = Arrays.asList("香蕉", "哈密瓜", "榴莲", "火龙果", "水蜜桃");
    List<String> newFruit = filter(fruit, (f) -> f.length() == 2);
    System.out.println(newFruit);
}
  • Consumer
private static void donation(Integer money, Consumer<Integer> consumer){
    consumer.accept(money);
}
public static void main(String[] args) {
    String name = "This's Demo";
    Consumer c = (event) -> System.out.println(name);
    donation(1, money -> System.out.println("好心的麦乐迪为Blade捐赠了"+ money +"元")) ;
}
  • Function
public class UserFunction implements Function<User,Boolean> {
@Override
public Boolean apply(User integer) {
    return null;
}
public static Boolean getNameLengthThan3(User user,UserFunction userFunction){
    return userFunction.apply(user);
}


public static Integer convert(String str, Function<String, Integer> function) {
    return function.apply(str);
}
public static void main(String[] args) {
    Integer value = convert("28", x -> Integer.parseInt(x));
}
  • Supplier
public static List<Integer> supply(Integer num, Supplier<Integer> supplier){
    List<Integer> resultList = new ArrayList<Integer>() ;
    for(int x=0;x<num;x++)
        resultList.add(supplier.get());
    return resultList ;
}
public static void main(String[] args) {
    List<Integer> list = supply(10,() -> (int)(Math.random()*100));
    list.forEach(System.out::println);
}
  • BinaryOperator
BinaryOperator<Long> addLongs = (x, y) -> x + y;
System.out.println(addLongs.apply(4l, 5l));   // 9

2019年3月27日

results matching ""

    No results matching ""