作者PsMonkey (痞子军团团长)
看板Translate-CS
标题[翻译] Java 8 取出 Collection element 的方式
时间Wed Apr 3 12:42:59 2013
原文网址:
http://www.javacodegeeks.com/2013/03/
extracting-the-elements-of-the-java-collection-the-java-8-way.html
译文网址:
http://blog.dontcareabout.us/2013/04/java-8-collection-element.html
BBS 使用 markdown 格式撰写
译文中的 Collection,代表 Collection API
或是属於 Collection 的各个 class(List、Map...)。
如果是 collection,则代表某个 Collection 的 instance。
______________________________________________________________________
我们都广泛使用 Collection,
像是 `List`、`Map` 以及延伸的 class。
每次我们用的时候,我们都得扫遍整个 collection 去找到某些 element、
更新它们、或是找出某个条件下不同的 element。
就像下面这个 `Person` 的 `List`:
List<Person> personList = new ArrayList<>();
personList.add(new Person("Virat", "Kohli",22));
personList.add(new Person("Arun", "Kumar",25));
personList.add(new Person("Rajesh", "Mohan", 32));
personList.add(new Person("Rahul", "Dravid", 35));
要找出 `Person` 的年龄大於 30 的 instance,我们会这样作:
List<Person> olderThan30OldWay = new ArrayList<>();
for ( Person p : personList){
if ( p.age >= 30){
olderThan30OldWay.add(p);
}
}
System.out.println(olderThan30OldWay);
就会得到这样的输出结果:
[Rajesh Mohan, 32, Rahul Dravid, 35]
程式码是很好写,但会不会有点罗唆、尤其是回圈的部份?
为甚麽我们得要有回圈呢?
如果有 API 可以扫描内容、然後给我们最终结果,
例如我们给一个 `List`、然後用一串 method 之後
就可以取得我们想要的 `List` 结果?
有的,在 Scala、Groovy 这种有支援 closure、
也支援内部回圈的语言就有可能做到。
但是有给 Java 开发人员的解决方案吗?
有的,这个问题在导入 [Lambda Expression(closure)] 後,
利用 lambda expression 来 [加强 Collection API][sotc3],就可以解决。
不过坏消息是,这会是 Java 8 的一部分,
[需要一点时间]才会变成主流的开发方式。
[Lambda Expression(closure)]:
http://openjdk.java.net/projects/lambda/
[sotc3]:
http://cr.openjdk.java.net/~briangoetz/lambda/sotc3.html
[需要一点时间]:
http://openjdk.java.net/projects/jdk8/milestones
在上面的情境中使用 Java 8 的强化功能
====================================
正如我知前所说,Collection API 正在补强以支援 lambda expression,
你可以在[这篇文章][sotc3]中了解更多内容。
JDK 团队并不是把所有新的 API 加到 Collection 当中,
而是创造了一个新的概念 `Stream`,
并且把大部分的 API 加到那个 class 当中。
`Stream` 是 element 的序列,在建立时从 collection 取得。
要了解更多 `Stream` 的起源,请参考[这篇文章][sotc3]。
要实作这个范例,我开始使用 Java 8 的强化功能、一些新的 API:
`stream()`、`filter()`、`collect()`、`Collectior.toCollection()`。
* [stream()]:collection 用这个 API 可以建立一个 [Stream] 的 instance。
* [filter()]:这个 method 接收一个
会回传 boolean 值的 lambda expression。
这个 lambda expression 会替换成 [Predicate] class 的实作。
* [collect()]:有两个 overloaded 的版本。我在这边用其中一个,
可以取得 [Collector] 的 instance。
这个 method 会取得 stream 的内容然後建立另一个 collection,
建立的逻辑在 [Collector] 当中定义。
* [Collectors.toCollection()][toCollection()]:
[Collectors] 是 [Collector] 的 factory(pattern)。
[toCollection()] 需要一个可以回传任何 Collection class instance
的 lambda expression / method reference。
[stream()]:
http://download.java.net/lambda/b81/docs/api/
java/util/Collection.html#stream()
[Stream]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Stream.html
[filter()]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Stream.html#filter(java.util.function.Predicate)
[Predicate]:
http://download.java.net/lambda/b81/docs/api/
java/util/function/Predicate.html
[collect()]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Stream.html#collect(java.util.stream.Collector)
[Collector]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Collector.html
[toCollection()]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Collectors.html
#toCollection(java.util.function.Supplier)
[Collectors]:
http://download.java.net/lambda/b81/docs/api/
java/util/stream/Collectors.html
简单介绍要用的 API 之後,让我来展示一下跟第一个范例等意的程式码:
List<Person> olderThan30 =
//Create a Stream from the personList
personList.stream().
//filter the element to select only those with age >= 30
filter(p -> p.age >= 30).
//put those filtered elements into a new List.
collect(Collectors.toCollection(() -> new ArrayList<Person>()));
System.out.println(olderThan30);
上面的程式码使用内部回圈以及 lambda expression
让它看起来直觉、简洁、还可以舒缓眼睛不适。
(译注:我承认最後一个是恶搞乱翻的 [逃])
如果你不熟悉 lambda expression 的想法,
可以看一下我[之前写的文章],里头有简单的介绍。
[之前写的文章]:
http://blog.sanaulla.info/2013/03/11/
using-lambda-expression-to-sort-a-list-in-java-8
-using-netbeans-lambda-support/
--
钱锺书:
说出来的话
http://www.psmonkey.org
比不上不说出来的话
Java 版 cookcomic 版
只影射着说不出来的话
and more......
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.25.29.173
Update:校正翻译错误
※ 编辑: PsMonkey 来自: 114.25.29.173 (04/03 15:22)