简洁Java之道

计算机专家在问题求解时非常重视表达式简洁性的价值。Unix的先驱者Ken Thompson曾经说过非常著名的一句话:“丢弃1000行代码的那一天是我最有成效的一天之一。”这对于任何一个需要持续支持和维护的软件项目来说,都是一个当之无愧的目标。早期的Lisp贡献者Paul Graham甚至将语言的简洁性等同为语言的能力。这种对能力的认识让可以编写紧凑、简介的代码成为许多现代软件项目选择语言的首要标准。

\\

任何程序都可以通过重构,去除多余的代码或无用的占位符,如空格,变得更加简短,不过某些语言天生就善于表达,也就特别适合于简短程序的编写。认识到这一点之后,Perl程序员普及了代码高尔夫竞赛;其目标是用尽可能短的代码量解决某一特定的问题或者实现某个指定的算法。APL语言的设计理念是利用特殊的图形符号让程序员用很少量的代码就可以编写功能强大的程序。这类程序如果实现得当,可以很好地映射成标准的数学表达式。简洁的语言在快速创建小脚本时非常高效,特别是在目的不会被简洁所掩盖的简洁明确的问题域中。

\\

相比于其他程序设计语言,Java语言的冗长已经名声在外。其主要原因是由于程序开发社区中所形成的惯例,在完成任务时,很多情况下,要更大程度地考虑描述性和控制。例如,长期来看,长变量名会让大型代码库的可读性和可维护性更强。描述性的类名通常会映射为文件名,在向已有系统中增加新功能时,会显得很清晰。如果能够一直坚持下去,描述性名称可以极大简化用于表明应用中某一特定的功能的文本搜索。这些实践让Java在大型复杂代码库的大规模实现中取得了极大的成功。

\\

对于小型项目来说,简洁性则更受青睐,某些语言非常适于短脚本编写或者在命令提示符下的交互式探索编程。Java作为通用性语言,则更适用于编写跨平台的工具。在这种情况下,“冗长Java”的使用并不一定能够带来额外的价值。虽然在变量命名等方面,代码风格可以改变,不过从历史情况来看,在一些基本的层面上,与其他语言相比,完成同样的任务,Java语言仍需更多的字符。为了应对这些限制,Java语言一直在不断地更新,以包含一些通常称为“语法糖”的功能。用这些习语可以实现更少的字符表示相同功能的目标。与其对应的更加冗长的配对物相比,这些习语更受程序开发社区的欢迎,通常会被社区作为通用用法快速地采用。

\\

本文将着重介绍编写简洁Java代码的最佳实践,特别是关于JDK8中新增的功能。简而言之,Java 8中Lambda表达式的引入让更加优雅的代码成为可能。这在用新的Java Streaming API处理集合时尤其明显。

\\

冗长的Java

\\

Java代码冗长之所以名声在外,一部分原因是由于其面向对象的实现风格。在许多语言中,只需要一行包含不超过20个字符的代码就可以实现经典的“Hello World”程序示例。而在Java中,除了需要类定义中所包含的main方法之外,在main方法中还需要包含一个方法调用,通过System.out.println()将字符串打印到终端。即使在使用最少的方法限定词、括号和分号,并且将所有空格全都删除的极限情况下,“Hello World”程序最少也需要86个字符。为了提高可读性,再加上空格和缩进,毋庸置疑,Java版的“Hello World”程序给人的第一印象就是冗长。

\\

Java代码冗长一部分原因还应归咎于Java社区将描述性而非简洁性作为其标准。就这一点而言,选择与代码格式美学相关的不同标准是无关紧要的。此外,样板代码的方法和区段可以包含在整合到API中的方法中。无需牺牲准确性或清晰度,着眼于简洁性的程序代码重构可以大大简化冗余Java代码。

\\

有些情况下,Java代码冗长之所以名声在外是由于大量的老旧代码示例所带来的错觉。许多关于Java的书籍写于多年之前。由于在整个万维网最初兴起时,Java便已经存在,许多Java的在线资源所提供的代码片段都源自于Java语言最早的版本。随着时间的推移,一些可见的问题和不足不断得到完善,Java语言也日趋成熟,这也就导致即使十分准确并实施的当的案例,可能也未能有效利用后来的语言习语和API。

\\

Java的设计目标包括面向对象、易于上手(在当时,这意味着使用C++格式的语法),健壮、安全、可移植、多线程以及高性能。简洁并非其中之一。相比于用面向对象语法实现的任务,函数式语言所提供的替代方案要简洁的多。Java 8中新增的Lambda表达式改变了Java的表现形式,减少了执行许多通用任务所需的代码数量,为Java开启了函数式编程习语的大门。

\\

函数式编程

\\

函数式编程将函数作为程序开发人员的核心结构。开发人员可以以一种非常灵活的方式使用函数,例如将其作为参数传递。利用Lambda表达式的这种能力,Java可以将函数作为方法的参数,或者将代码作为数据。Lambda表达式可以看作是一个与任何特定的类都无关的匿名方法。这些理念有着非常丰富多彩并且引人入胜的数学基础。

\\

函数式编程和Lambda表达式仍然是比较抽象、深奥的概念。对于开发人员来说,主要关注如何解决实际生产中的任务,对于跟踪最新的计算趋势可能并不感兴趣。随着Lambda表达式在Java中的引入,对于开发人员来说对这些新特性的了解至少需要能够达到可以读懂其他开发人员所编写代码的程度。这些新特性还能带来实际的好处——可以影响并发系统的设计,使其拥有更优的性能。而本文所关心的是如何利用这些机制编写简洁而又清晰的代码。

\\

之所以能够用Lambda表达式生成简洁的代码,有如下几个原因。局部变量的使用量减少,因此声明和赋值的代码也随之减少。循环被方法调用所替代,从而将三行以上的代码缩减为一行。本来在嵌套循环和条件语句中的代码现在可以放置于一个单独的方法中。实现连贯接口,可以将方法以类似于Unix管道的方式链接在一起。以函数式的风格编写代码的净效应并不只限于可读性。此类代码可以避免状态维护并且不会产生副作用。这种代码还能够产生易于并行化,提高处理效率的额外收益。

\\

Lambda表达式

\\

与Lambda表达式相关的语法比较简单直白,不过又有别于Java之前版本的习语。一个Lambda表达式由三部分组成,参数列表、箭头和主体。参数列表可以包含也可以不包含括号。此外还新增了由双冒号组成的相关操作符,可以进一步缩减某些特定的Lambda表达式所需的代码量。这又称为方法引用

\\

线程创建

\\

在这个示例中,将会创建并运行一个线程。Lambda表达式出现在赋值操作符的右侧,指定了一个空的参数列表,以及当线程运行时写到标准输出的简单的消息输出。

\\
\Runnable r1 = () -\u0026gt; System.out.print(\"Hi!\");\ \r1.run()\
\\
\\t\t\t

参数列表

\\t\t\t
\\t\t\t

箭头

\\t\t\t
\\t\t\t

主体

\\t\t\t
\\t\t\t

()

\\t\t\t
\\t\t\t

-\u0026gt;

\\t\t\t
\\t\t\t

System.out.print(\"Hi!\");

\\t\t\t

处理集合

\\

Lambda表达式的出现会被开发人员注意到的首要位置之一就是与集合API相关。假设我们需要将一个字符串列表根据长度排序。

\\
\java.util.List\u0026lt;String\u0026gt; l;\l= java.util.Arrays.asList(new String[]{\"aaa\
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值