龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

Java函数式编程(三):列表的转化

时间:2014-09-26 03:25来源:网络整理 作者:网络 点击:
分享到:
这篇文章主要介绍了Java函数式编程(二):列表的转化,lambda表达式不仅能帮助我们遍历集合,并且可以进行集合的转化,需要的朋友可以参考下

列表的转化

将集合转化成一个新的集合就和遍历它一样简单。假设我们要将列表中的名字转化成全大写的。我们看下都有哪些实现方式。

Java中的字符串是不可变的,所以它没法改变。我们可以生成新的字符串,用来替换列表中原有的元素。然而这样做的话,原来列表就没了;还有一个问题,原来的列表可能也是不可变的,比如Arrays.asList()生成的,所以修改原来的列表这招不行。还有一个缺点就是这样做很难并行操作。

生成一个新的全大写的列表是个不错的选择。

乍听起来这个建议弱爆了;性能是我们都很关注的一个问题。令人吃惊的是,函数式编程通常要比命令式的性能要高,我们在153页的性能问题中会讲到。

我们先开始用这个集合生成一个大写字母的新集合吧。

复制代码 代码如下:

final List<String> uppercaseNames = new ArrayList<String>();
for(String name : friends) {
uppercaseNames.add(name.toUpperCase());
}

在命令式的代码中,我们先创建一个空列表,然后把大写的名字填充进去,在遍历原来列表的过程中,每次插入一个。为了改进成函数式的版本,我们第一步可以考虑采用19页遍历列表中提到的那个内部迭代器forEach来替换一下for循环,正如下例所示的那样。
复制代码 代码如下:

final List<String> uppercaseNames = new ArrayList<String>();
friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
System.out.println(uppercaseNames);

我们用了内部迭代器,但还得新建一个列表,然后再把元素插入到里面。我们还可以进一步改进。

使用lambda表达式

一个新引入的Stream接口里面,有个map方法,它可以帮助我们远离可变性,并使代码看起来更简洁。Steam有点像集合的迭代器,同时它还提供了流函数(fluent functions)的功能。使用这个接口的方法,我们可以把一系列调用给组合起来,使代码读起来就像描述问题的顺序一样,可读性更强。

Steam的map方法可以用来将输入序列转化成一个输出的序列——这和我们要做的工作非常匹配。

复制代码 代码如下:

friends.stream()
.map(name -> name.toUpperCase())
.forEach(name -> System.out.print(name + " "));
System.out.println();

JDK8中的所有集合都支持这个stream方法,它把集合封装成一个Steam实例。map方法对Stream中的每个元素都调用了指定的lambda表达式或者代码块。map方法跟forEach方法很不一样, forEach只是简单的对集合中的元素执行了一下指定的函数。而map方法把lambda表达式的运行结果收齐起来,返回一个结果集。最后我们用forEach方法打印了所有的元素。

新集合中的名字全都是大写的了:

复制代码 代码如下:

BRIAN NATE NEAL RAJU SARA SCOTT

map方法很适合把一个输入集合转化成一个新的输出集合。这个方法确保了输入输出序列的元素的数量是相同的。然而输入元素和输出元素的类型可以是不一样的。在这个例子中,我们输入和输出的都是字符串的集合。我们可以传给map方法一段代码,让它返回比如说名字中包含字符的个数。这样的话,输入的还是字符串的序列,而输出的却是数字序列了,就像下面这样。

复制代码 代码如下:

friends.stream()
.map(name -> name.length())
.forEach(count -> System.out.print(count + " "));

结果是每个名字中字母的个数:
复制代码 代码如下:

5 4 4 4 4 5

精彩图集

赞助商链接