Java 8中同时存在面向对象编程(OOP)和函数式编程(FP, Functional Programming)这两种编程范式。实际上,这两种范式并不矛盾,只是着重点不同。在OOP中,着重于通过丰富的类型系统对需要解决的问题进行建模;而FP中则着重于通过高阶函数和Lambda表达式来完成计算。所以我们完全可以将这两者融合在一起,对问题提出更加优雅的解决方案。
在这篇文章中,会介绍如何通过函数组合(Function Composition)来将若干个函数单元组合成一个Map-Reduce模式的应用。同时,还会介绍如何将整个计算过程并行化。
使用函数组合
在使用函数式编程的时候,函数是组成程序的单元。通过将函数以高阶函数的形式组织,可以有效地提高不变性(Immutability),从而减少程序的状态变化,最终让并行化更加容易。
下面这张图反映了,纯粹的面向对象设计和混合式设计(面向对象和函数式)的风格。
在OOP中,对象的状态会随着程序的进行而不断发生变化,但是对象始终只有一个。 而在FP中,对象每次被一个函数处理之后,都会得到一个新的对象,而原来的对象并不会发生变化。
下面是一个小例子,让你对这种混合式的编程范式有一个初步的了解。假设我们有一些股票的代码,需要得到股票价格大于100美元的股票并对它们进行排序:
public class Tickers {
public static final List<String> symbols = Arrays.asList(
"AMD", "HPQ", "IBM", "TXN", "VMW", "XRX", "AAPL", "ADBE",
"AMZN", "CRAY", "CSCO", "DELL", "GOOG", "INTC", "INTU",
"MSFT", "ORCL", "TIBX", "VRSN", "YHOO");
}
对于每只股票代码,可以通过调用下面这段程序借助Yahoo提供的Web Service来得到对应的股价:
public class YahooFinance {
public static BigDecimal getPrice(final String ticker) {
try {
final URL url = new URL("http://ichart.finance.yahoo.com/table.csv?s=" + ticker);
final BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
final String data = reader.lines().skip(1).findFirst().get();
final String[] dataItems