如何避免Lambda表达式毁了你的世界
本文由 ImportNew - 陈 秋林 翻译自 zeroturnaround。欢迎加入Java小组。转载请参见文章末尾的要求。
代码与野兽
在Java8中,引入的Lambda表达式(译者注:来自函数式编程思想)无疑是最受关注的。但是自这个新闻被公布的几个月以来,我还没见到过有哪些项目是Lambda起着关键作用的。
确实,众人所知的Lambda表达式一直被学术界、研讨会和社区宣扬对java是百利而无一害。但是经过时间的考验后,Lamdba是否依然像培根芝士汉堡那样美妙而又让人称赞呢?你又是否会因为日常工作需要用到它而去寻找更多关于Lamdba的资料呢?
让我们马上来看看奇妙的Lambda表达式在我们的代码中的运用:
public class RuinLambdas { public static void main(String[] args) { // Easy startDream(new Dream() { @Override public void dream() { // Dream boy, dream ... } }); startDream(new AugmentedDream() { @Override public void dream(String dreamName) { // Dream boy, dream ... } }); // Less easy startDream(() -> { /* Dream boy, dream ... */ }); // And now kid ? ... startDream((dreamName) -> { /* Dream boy, dream ... */ }); // Do you see which one it is directly by reading this ? ... startDream((dreamName, duration) -> { /* Dream boy, dream ... */ }); } public static void startDream(Dream md) { md.dream(); } public static boolean startDream(AugmentedDream ad) { ad.dream("Ruin lambdas"); return true; } public static boolean startDream(ThisIsNightmare hahaha) { hahaha.sufferMyKid("Hahaha you're going to hell", 2000); return false; } } interface Dream { void dream(); } interface AugmentedDream { void dream(String dreamName); } interface ThisIsNightmare { void sufferMyKid(String dreamName, int duration); }
代码内容:一个类有三个方法,开始做美梦,还有另外一个方法,是做噩梦的。
该如何看待、使用、欣赏以及理解(Lamdba)?
通过注释,我们可以很简单的明白一些事实:
- 通过每个方法的直接调用我们知道使用哪个接口;
- 通过每个调用我们知道哪些方法被实现了;
- 就算没有解释,代码一样简洁易读;
- 开发人员不需要理解代码的每一个细节;
- 初级开发人员加入团队并没有迷失在代码荒漠中。
那接下来是否应该讲讲怎样使用Lambda了?不,如果这样的话就跟前文相抵触了。
的确,对于绝大部分不善于编程的人来说,这些代码并不那么易读了。你可能会反驳:只要你看看下面的注释就明白所有(代码)了。是不是这样呢?可能在某些情况下,的确如此,但是生活可不像你开着法拉利在空荡的高速公路上一样畅通无阻。为什么会这样?
谁最不喜欢Lambda?
成为一个Lambda十分的艰难,把难读且难用的Lambda当作一个人的话,问问他这些问题:你有没有一些简单的项目是所有的代码都写在一个类里面的?你有没有维护过几个星期以前甚至是几个月以前的代码?你没有写过代码了吗?
在现实生活中,你用Maven或者Gradle来管理依赖。你也基本上是用IDE来开发你的应用吧?通过这两件事你可能理解Lambda的难用了。
日常工作中的Lambda和依赖管理
开发中,你一般都没有(去找)你用的库的源代码。当你用了Lamdba这样简洁的语法的时候,你就必须通过浏览API文档来使用这些库了。当你不能理解你使用的库的时候,你可能需要花几个小时去理解库函数做了什么。而Lamdba简洁的语法对你理解这些代码没有任何帮助。
当Lambda没有IDE
我们都习惯使用IDE中Ctrl +点击的快捷方式帮我们找源代码的声明、实现。用的很爽是吧?别以为这是IDE必须做的,假如没有IDE,你要在你的服务器上用 vi 来写你的java代码了(vi?这是什么时代的东西了:)),到时候你会用不一样的态度来看待IDE了。
在“不懂就GOOGLE的时代”,你会说让你理解这些代码不是什么难事。以程序员的经验来说,确实如此。如果你的Java足够好的话,你甚至可以通过在虚拟机里查看、编写字节码来理解程序。但是当你正着手一个新项目,而且因为你的上司看到你找一个bug找了几个星期没找出来的时候,你就会焦虑起来,事情也会变得棘手了。
Lambda有个矛盾就是它的语法写起来简单但是却难以理解,除非你对它十分熟悉。所以,如果你要快速弄清楚代码做了什么,即使它简化了Java的语法,但是lambda让代码变得抽象,难以迅速的理解。
Lambda——我依然爱你
就算这文章有损lambda表达式在Java8变革中的声誉,我还是爱他们。事实上,如果你已经习惯了他们,他们真的很好用,主要用于快速处理列表中每个元素的值。
对于复杂的算法也许有些开发者会认为以上的观点不正确。 Java的从来就不是一个函数式语言,但现在Lambda却成为了Java的核心。个人认为事事无绝对的好坏,我们不可能只保留Lambda的好处又让它变得易读吧?上下文是很重要的,你不会开着载着水泥的卡车跑去超市就为了买瓶牛奶吧?
我不确定我是否是唯一一个对Java8引入lambda抱有一百分感兴趣的人,你可以留下您的意见,无论你是否同意我的看法。
最后,我想给你留下一个小小的Lambda表达式(作为礼物)……
readers.stream() .filter(reader -> reader.isNinja()) .forEach(reader -> reader.cheers());
原文链接: zeroturnaround 翻译: ImportNew.com - 陈 秋林
译文链接: http://www.importnew.com/10480.html
[ 转载请保留原文出处、译者和译文链接。]
相关文章
- 征集参与Java 8原创系列文章作者
- Java8-本地缓存
- Java8中的java.util.Random类
- JavaSE 8—新的时间和日期API
- Java8 性能提升:LongAdder vs AtomicLong
- Java8:Lambda序列化?
- 鲜为人知的Java8特性:泛化目标类型推断
- Java8学习:Lambda表达式、Stream API和功能性接口 — 教程、资源、书籍和实例
- Java 8新特性——default方法(defender方法)介绍
- Java 8 Optional类深度解析