我使用Java 8编码已经有些年头,既用于新的应用程序,也用来迁移现有的应用,感觉是时候写一些我发现的非常有用的“最佳实践”。我个人并不喜欢“最佳实践”这个说法,因为它意味着“一刀切”的解决方案,而编码不可能是这样的工作方式——我们需要亲自去发现什么样的解决方案才是有效的。但是我发现了一些Java 8代码中可以帮助我们的一些选择,让我们一起来看看吧。

1.Optional

Optional是一个严重被低估的功能,并且有潜力删除很多困扰我们的NullPointerExceptions。这在代码边界中(要么是正在使用的API,要么是正在暴露的API)特别有用,因为它允许你和你的调用代码来推理所期待的东西。

然而,不加思考和设计就应用Optional可能会导致影响大量的类,并可能导致可读性更差。下面是一些关于如何高效使用Optional的技巧。

Optional应该只用于返回类型

……不是参数,也不是字段。幸运的是,IntelliJ IDEA的让你打开检查来查看是是否遵循这些建议。

Optional值应在遇到它们的地方中处理。IntelliJ IDEA的建议会防止代码Optional泄漏,所以请记得在你发现Optional的地方处理它,迅速采取行动。

不应该简单调用get()

Optional的功能是表达这个值可能是空的,并让你应对这种情况。因此,在对它做任何事情之前一定要检查是否有一个值。只是简单得调用get()而不先检查isPresent()在某些时候可能会导致空指针。幸运的是,IntelliJ IDEA也有检查可以提醒你这一点。

可能有更优雅的方式

结合了get()的isPresent()当然会很赞…

……但也有更优雅的解决方案。你可以使用orElse在万一是空值的情况下给一个替代方案。

……或者你可以使用orElseGet说明在值为空的情况下调用哪个方法。这似乎与上面的例子相同,但supplier方法将只在需要的时候调用,因此,如果这是一种昂贵的方法,那么使用lambda会有更佳性能。

2.使用Lambda表达式

Lambda表达式是Java 8的主要特点之一。即使你还没有使用Java 8,你现在可能已经对它们有了基本的了解。它们是用Java编程的一种新的方式,并且什么是“最佳实践”还不明显。下面是我喜欢遵循的一些指引。

保持简短

函数式程序员与较长的lambda表达式相处会更愉快,但那些淫浸于Java多年的人会发现保持lambda表达式为区区几行代码更容易。你甚至可能更愿意将其限制到一行代码,并且你可以轻松重构较长的表达式为一个方法。

这些甚至可能会成为方法引用。方法引用一开始会觉得有点陌生,但实际上坚持方法引用是有价值的,因为它们在某些情况下有助于可读性,后面我会讨论到这一点。

明确

类型信息缺少lambda表达式,所以你可能会觉得包含类型信息用于参数会很有用。

正如你所见,这回变得相当笨拙。所以我更喜欢给参数取一个有用的名字。当然,不管你有没有这么做,IntelliJ IDEA可以让你看到参数得类型信息。

甚至是lambda所代表的函数式接口:

3.针对Lambda表达式设计

我认为lambda表达式有点像泛型——和泛型一起,我们经常使用它们(例如,添加类型信息到List< >),但最好我们可以设计一种方法或一个具有泛型类型(例如Person< T >)的类。同样的,当使用类似于Streams API的东西时,我们会传递lambda表达式,但更好的是创造一个需要lambda参数的方法。

但是,如果你发现自己处于这类情况下,下面有一些超棒的技巧。

IntelliJ IDEA可以帮你引进函数式参数

这让你可以在有人将传递一个lambda而非Object的地方创建一个参数。此功能的好处是,它表明,现有函数式接口匹配规格说明。

这会导致…

使用现有的函数式接口

随着开发人员越来越熟悉Java 8代码,我们就能知道当使用如Supplier和 Consumer的接口时,会发生什么,以及创建一个本地的ErrorMessageCreator(举个例子)可能会造成混乱,而且浪费。看看这个函数包了解一下哪些已经是可用的。

添加@FunctionalInterface到函数式接口

如果你确实需要创建自己的函数式接口,那么就这样用此注释标记。这似乎没有太大的作用,但IntelliJ IDEA会告诉你,在你的接口不能匹配用于函数式接口的异常的时候。当你没有指定要覆盖的方法时,它会标志:

当你指定了太多方法的时候,它会标志:

并且如果你应用它到一个类而不是接口时,它会警告你:

lambda表达式可用于带有一个单一抽象方法的任何接口,但它们不能用于符合相同标准的抽象类。似乎不合逻辑,但就是这样。

4.Stream

Stream API是Java 8另一个大特点,并且我认为我们还真的不知道这对我们的编码方式会产生多大的改变。下面是我发现的一些有用的东西

排队点操作符

我个人更喜欢排队我的流操作。当然,你没有必要这样,当我发现这样做对我有帮助:

  • 一目了然地看到我有哪些操作

  • 调试更容易(虽然IntelliJ IDEA确实提供了对一行中的任意多个lambda表达式设置断点的能力,但是拆分到不同的行会变得更简单)

  • 当我测试东西的时候注释操作

  • 轻松插入peek()用于调试或测试

此外,在我看来,它更整洁。如果我们按照这个模式,在减少代码行数方面我们并没有增加很多。

你可能需要调整格式设置以排列点操作符。

使用方法引用

是的,确实需要一段时间来适应这个奇怪的语法。但是,如果使用得当,它确实可以增加可读性。请看:

与(相对)新的Objects类上的辅助方法相比较:

后者的代码对于哪些值是要保存的更加明确。当lambda可以被折叠到方法参考的时候,IntelliJ IDEA通常会让你知道。

当遍历一个集合时,在可行的情况下使用Streams API

…或者新的集合方法,如forEach。IntelliJ IDEA给你建议是:

一般使用Streams API比循环和if语句的组合更加明确。例如:

IntelliJ IDEA建议这可重构为:

我所做的性能测试表明这种重构令人惊讶——并不总是可预测性能是保持不变,改善还是变得更糟。与往常一样,如果性能在应用程序中是关键,那么在交付一种风格到另一种之前衡量它。

遍历数组时使用循环

但是,使用Java 8并不一定意味着你必须到处使用流和新的集合方法。IntelliJ IDEA会建议转换成流,但是,这并不意味着你必须回答“yes”(记得检查是可以抑制或关闭的)。

特别是,遍历原始类型的小型数组几乎肯定会用,以获得更好的性能循环,很可能(至少对于Java开发人员是新的流)更具可读性。

与任何技巧一样,规则并不是一成不变的,但你应该决定是尽可能地使用Streams API,还是依然对一些操作使用循环。总之,要一致。

最后

每天都在发现新的东西,并且有时候我的偏好会发生变化——例如,方法引用,我曾经深恶痛绝并且避免在我的代码中使用。现在我很想听听你的秘诀!

Java 8开发的4大顶级技巧的更多相关文章

  1. Java开发想尝试大数据和数据挖掘,如何规划学习?

    大数据火了几年了,但是今年好像进入了全民大数据时代,本着对科学的钻(zhun)研(bei)精(tiao)神(cao),我在17年年初开始自学大数据,后经过系统全面学习,于这个月跳槽到现任公司. 现在已 ...

  2. Java后端开发工程师是否该转大数据开发?

    撰写我对java后端开发工程师选择方向的想法,写给在java后端选择转方向的人 背景 看到一些java开发工程师,对java后端薪酬太悲观了.认为换去大数据领域就会高工资.觉得java后端没有前途.我 ...

  3. 2020年9大顶级Java框架

    诞生于1995年的Java,目前已在134,861个网站上广泛使用,包括ESPN.SnapDeal等.在其24年的成长史中,Java已经证明了自己是用于自定义软件开发的顶级通用编程语言. Java广泛 ...

  4. Java多线程开发技巧

    很多开发者谈到Java多线程开发,仅仅停留在new Thread(...).start()或直接使用Executor框架这个层面,对于线程的管理和控制却不够深入,通过读<Java并发编程实践&g ...

  5. Java Collection开发技巧

    Java Collection(集合) 集合中的一些技巧: 通过Collections类的静态方法,可以对集合进行一些操作 1 java.util.List<Integer> number ...

  6. 个人的java web开发书单

    首发至个人博客http://www.zidafone.com/blog/36 以下是对一些读过的书和一些买后随便翻了翻的书的个人感觉.都是java web开发的程序员可能接触的书,其他的如设计/手机开 ...

  7. 使用Eclipse+Maven+Jetty构建Java Web开发环境(几个教程综合集成2014发行)

    工作需要使用Jetty由于web集装箱,得知Eclipse+Maven+Jetty该组合是非常好的,因此,要在网上找了很多教程,但不写或多或少特定的或过时的内容而导致最终的配置失败,易于配置为未来的同 ...

  8. Java秋招面经大合集

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  9. ​​ ​​我的Java秋招面经大合集(包含BAT头条网易等公司)

    ​ 微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经 ...

随机推荐

  1. AA投资

    AA投资创建于2015年,总部位于北京,创始人成妙绮和王浩泽,专注于天使轮的技术创新驱动的TMT项目投资. 投资方向 AA投资是一家2015年才成立的风险投资机构,专注于种子轮.天使轮.Pre-A轮的 ...

  2. Intellij Idea 15 生成serialVersionUID的方法

    默认情况下Intellij IDEA是关闭了继承了Serializable接口的类生成serialVersionUID的警告.如果需要ide提示生成serialVersionUID,那么需要做以下设置 ...

  3. ftp下载显示进度

    经常用到ftp get命令下载东西,但是遇到大的文件不知道是挂了还是在运行,要是能显示就好了,于是就有了下文... 注: 红色 字体是我敲击的命令 “#” 是注释语 [root@localhost s ...

  4. 从SDE库文件手工删除SDE图层(转载)

    转载自:http://gis-conquer.blog.sohu.com/164467560.html 一.前言    虽然Catalog能解决这种问题,但是在特殊情况下也许这种方法有点用途.    ...

  5. git忽略文件【转】

    转自: http://cwind.iteye.com/blog/1666646 有很多文件不必使用git管理.例如Eclipse或其他IDE生成的项目文件,编译生成的各种目标或临时文件等.使用git ...

  6. Python 中 os.path模板

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...

  7. Mac 切换Windows 使用虚拟机, 不推荐双系统

     为什么使用虚拟机而不是双系统? 1.虚拟机可以随时在两个系统之间进行切换,便于在工作时使用而不影响效率.如果是双系统,在切换到另一个系统时需要关机重启,太过麻烦. 2.虚拟机除了运行Windows之 ...

  8. JSON 之 SuperObject(7): 可以省略的双引号

    在 JSON 中, 字符串应该在双引号中; 从上个例子才发现: 原来这个双引号可以省略, 有空格都行 当然只是在程序代码中可以省略, 对象会自动识别添加的. 即如此, 下面写法都可以: uses Su ...

  9. JavaScript高级程序设计之数据类型

    首先讲讲关于js文件放置的问题,如果把<script>放在head标签处,浏览器会先加载完该处的所有不使用defer属性的js文件再呈现页面的内容(浏览器在遇到body标签时才呈现内容), ...

  10. 使用multimap创建重复键关联容器

    在“使用 <map> 库创建关联容器”一文中,我们讨论了标准库中的 map 关联容器.但那只是 map 容器的一部分.标准库还定义了一个 multimap 容器,它与 map 类似,所不同 ...