Java函数式编码结构-好程序员

好程序员Java培训分享Java函数式编码结构 , 本文将探讨三种下一代JVM语言:Groovy、Scala和Clojure , 比较并对比新的功能和范例 , 让Java开发人员对自己近期的未来发展有大体的认识 , 下面我们一起来看一下吧 。
Java函数式编码结构-好程序员文章插图
当垃圾回收成为主流时 , 它消除了所有类别的难以调试的问题 , 使运行时能够为开发人员管理复杂的、容易出错的进程 。 函数式编程旨在为你编写的算法实现同样的优化 , 这样你就可以从一个更高的抽象层面开展工作 , 同时运行时执行复杂的优化 。
Java下一代语言并不都占用从命令式到函数式的语言频谱的同一位置 , 但都展现出函数功能和习语 。 函数式编程技术有明确定义 , 但语言有时为相同的函数式概念使用不同的术语 , 使得我们很难看到相似之处 。 在本期文章中 , 我比较了Scala、Groovy和Clojure的函数式编码风格并讨论了它们的优势 。
命令式处理
我要首先探讨一个常见问题及其命令式解决方案 。 假如给定一个名称列表 , 其中一些名称包含一个字符 。 系统会要求你在一个逗号分隔的字符串中返回名称 , 该字符串中不包含单字母的名称 , 每个名称的首字母都大写 。 实现该算法的Java代码如清单1所示 。
清单1.命令式处理
public class TheCompanyProcess {
public String cleanNames(List listOfNames) {
StringBuilder result = new StringBuilder();
for(int i = 0; i < listOfNames.size(); i++) {
if (listOfNames.get(i).length() > 1) {
result.append(capitalizeString(listOfNames.get(i))).append(",");
}
}
return result.substring(0, result.length() - 1).toString();
}
public String capitalizeString(String s) {
return s.substring(0, 1).toUpperCase() + s.substring(1, s.length());
}
}
由于你必须处理整个列表 , 解决清单1中问题最简单的方式是使用一个命令式循环 。 对于每个名称 , 都需要进行检查 , 确认其长度是否大于1 , 然后(如果长度大于1)将首字母大写的名称附加到result字符串 , 并在后面加逗号 。 最终字符串中的最后一个名称不应包含逗号 , 所以我将它从最后返回值中移走 。
在命令式编程中 , 建议你在较低级上别执行操作 。 在清单1中的cleanNames()方法中 , 我执行了三个任务:我筛选列表以消除单字符 , 将列表中每个名称的首字母变换为大写 , 然后将列表转化为一个字符串 。 在命令式语言中 , 我不得不为三个任务都使用同一低级机制(对列表进行迭代) 。 函数式语言将筛选、变换和转化视为常见操作 , 因此它们提供给你从不同视角解决问题的方式 。
函数式处理
函数编程语言与命令式语言的问题分类方式不同 。 筛选、变换和转化逻辑类别表现为函数 。 那些函数实现低级变换并依赖于开发人员来编写作为参数传递的函数 , 进而定制函数的行为 。 我可以用伪代码将清单1中的问题概念化为:
listOfEmps -> filter(x.length > 1) -> transform(x.capitalize) ->
convert(x, y -> x + "," + y)
利用函数式语言 , 你可以建模这一概念性解决方案 , 无需担心实现细节 。
Scala实现
清单2使用Scala实现清单1中的处理示例 。 它看起来就像是前面的伪代码 , 包含必要的实现细节 。
清单2.Scala处理
val employees = List("neal", "s", "stu", "j", "rich", "bob")
val result = employees
.filter(_.length() > 1)
.map(_.capitalize)
.reduce(_ + "," + _)
对于给定的名称列表 , 我首先筛选它 , 剔除长度不大于1的所有名称 。 然后将该操作的输出提供给map()函数 , 该函数对集合的每个元素执行所提供的代码块 , 返回变换后的集合 。 最后 , 来自map()的输出集合流向reduce()函数 , 该函数基于代码块中提供的规则将每个元素结合起来 。