java8 lambda_Java Lambdas简介

java8 lambda

java8 lambda

Java 8的主题是lambdas。 我已经注意到,对于许多Java程序员而言,lambda都是非常难的材料。 因此,让我们尝试对它们有一个基本的了解。

首先,lambda到底是什么? Lambda是一个匿名函数,与常规函数不同,它没有绑定到标识符(即,它没有名称)。 这些函数可以作为参数传递给其他函数(称为高阶函数)。

假设我们的应用程序必须从系统的不同位置写入一堆文件。 我们不想每次都处理已检查的异常[请参阅“ 异常:已检查和未检查”以获取有关已检查的异常的更多信息]。 因此,我们决定编写一个低级的writeToFile函数,该函数打开FileWriter并将其传递给可以安全地写入文件的函数。

使用此底层函数,我们编写以下代码。

writeToFile("todo.txt", new FileWriteFunction() {
    @Override
    public void apply(Writer file) throws IOException {
        file.write("learn about lambdas\n");
        file.write("learn stream API\n");
    }
})

我们传递给writeToFile的对象是FileWriteFunction的匿名实现[是匿名的,因为我们没有将其命名为类]。 它具有单个功能,因此可以有效地传递匿名功能。 在Java的世界中,这些有时称为回调。 可能您以前至少使用过几次,也许没有注意到。

该匿名对象实际上是lambda。 但这显然不像传递函数。 语法非常笨拙。 而这正是Java 8中的变化。

有了Java 8中对lambda的语法支持,代码的读取就像我们传递函数一样。 使用Java 8 lambda,我们将上述代码重写如下。

writeToFile("todo.txt", file -> {
    file.write("learn about lambdas\n");
    file.write("learn stream API\n");
})

这样更好它强调重要的代码,并隐藏了大部分笨拙的部分。

通常,lambda与闭包可互换使用(即词汇功能)。 虽然它们都是匿名函数,但闭包的定义是它是包含绑定变量的函数。 即,闭包包括一个引用表,该表包含对局部变量的引用。

例如,如果我们接受要写入文件的参数data ,则使用闭包。

void save(String data) {
    writeToFile("file.db", file -> file.write(data) );
}

匿名内部类限制对最终变量的访问,而闭包提供对任何变量的访问。 但是,变量实际上是闭包的最终变量,因此无法重新分配。

那么lambdas的编译呢? Java 8是否仅使用一种方法就匿名内部类仅提供了一勺语法糖?

不是,不是的确,它允许对任何单方法匿名内部类使用lambda语法。 但是lambda并没有被编译成内部类。 相反,编译器在定义的类中输出lambda$方法,并使用invokedynamic调度该调用。

因此,现在您知道了如何在Java 8中使用lambda。虽然lambda本身非常有用,但在将它们应用于集合时更是如此。

新的Stream API通过为集合提供功能更强大的API来替代迭代器: java.util.stream.StreamStream上最值得注意的功能是: collectfiltermapreduce

从一个简单的例子开始,这里是如何对列表中的所有数字求和。

asList(1,2,3,4,5).stream()
    .reduce(0, (acc, value) -> acc + value) // => 15

通过从零开始将每个值加到累加器上,可以减少序列。 为了进行比较,通常会编写一个循环。

int acc = 0;
for (int n : asList(1,2,3,4,5))
    acc += n;
acc // => 15

继续求和仅求奇数。 首先我们filter奇数,然后reduce

asList(1,2,3,4,5).stream()
    .filter(Predicates::odd)
    .reduce(0, (acc, n) -> acc + n) // => 9

filter的参数是对我使用的Predicates类中的静态odd函数的函数引用。 顾名思义,这是一个布尔函数,用于测试数字是否为奇数。

到现在为止还挺好。 现在假设我们想将厘米大小的列表转换为以英寸为单位的等效大小。 我们为此使用map

List<Inch> inches = centimeters.stream()
    .map(Centimeter::toInches)
    .collect(Collectors.toList())

通过将toInches函数应用到centimeters集合中的每个项目,将centimeters映射为英寸。

从本质上讲, Stream是连续的。 它用于描述要应用于集合的操作。 但是要获得结果,必须收集数据。 这就是collect功能的目的。 它将流的元素简化为可变容器(例如,列表)。

使用Stream API和lambda可以大大简化用于集合的代码,并使代码更具表现力。 与使用破坏性操作(例如forEach )相比,首选使用非破坏性操作(例如mapfilter )使代码更易于推理。

而已! 这些是您需要了解的Java 8中的lambda(和闭包)的基础知识。当然,关于lambda的内容还有很多要写的,但这是另一篇文章。

参考: Software Craft博客上的JCG合作伙伴Bart Bakker对Java lambda的介绍

翻译自: https://www.javacodegeeks.com/2013/10/introduction-to-java-lambdas.html

java8 lambda

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值