作者coolcomm (coolcomm)
看板java
标题Re: [翻译] Java 8 取出 Collection element 的方式
时间Wed Apr 3 19:20:40 2013
※ 引述《brianhsu (坟墓)》之铭言:
: ※ 引述《PsMonkey (痞子军团团长)》之铭言:
: : 来闲聊一下...
: : 说真的,我觉得这个范例糟糕透了
: : 怎麽看都觉得第一个比较简单阿... [翻桌]
: : 不然光比较字数也可以阿... Orz
: 我没有仔细看文章,所以不确定是不是 API 设计上的问题。XD
: 但是在 Scala 里面因为 filter 本身回传的就是另一个同种类的 Collection,
: 例如你是 List.filter 他就会回传另一个 List,你是 Set.filter 就会回传
: 另一个 Set,所以会 filter 版会比 loop 版来得简洁:
: case class Person(name: String, age: Int)
: val personList = List(Person("Man1", 30), Person("Man2", 40))
: val olderThan30 = personList.filter(_.age > 30)
: Java 的版本看起来比较复杂应该是多了後面那个 collect 和前面的 stream 吧?
: 其实主要的逻辑只有 filter 而已,如果 Java 的版本能够变成:
: List<Person> olderThan30 = personList.filter(p -> p.age > 30)
: 就会比回圈式的简单易懂多啦。XDDD
Java 之所以没有如此实作,
是因为在 Java 的 collection 中,传回原本型态的新 instance 并不是那麽简单的事。
* * *
假设标准 library 中的 `LinkedList<T>` 有一个 `filter` 方法
public class LinkedList<T> extends ... implements .... {
// ...
public LinkedList<T> filter(Predicate<T> pred) {
// ...
}
// ...
}
现在我们想用 `RichLinkedList<T>` 扩充 `LinkedList<T>` 的功能
我们让 `RichLinkedList<T>` 继承 `LinkedList<T>`
class RichLinkedList<T> extends LinkedList<T> {
void dummy() {}
}
这样应该是没问题吧......
new RichLinkedList<Object>().dummy();
但这样就会出事了:
new RichLinkedList<Object>().filter(x -> true).dummy();
// compile time error
因为 `filter` 传回的事实上是一个 `LinkedList` 而非 `RichLinkedList` !
有没有解决方法?
在 Java 里,
除了把这些方法全部 @Override 之外,答案似乎是没有......
而在 Scala 中, `filter`, `map` ...... 等方法会接收一个 `CanBuildFrom` 型态的
implicit parameter ...... (下略)
* * *
我承认我其实也搞不懂 `CanBuildFrom` ...... OTZ
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.43.179.206
1F:推 stimim:嗯,java 继承了以後回传型态不会跟着升级有时候很烦 04/03 19:24
※ 编辑: coolcomm 来自: 114.43.179.206 (04/03 19:49)
2F:推 Chikei:CanBuildFrom概念上是Builder factory,所以scala可以说是 04/04 03:33
3F:→ Chikei:会推导范例里collect()所需参数,并在前面的call一并执行 04/04 03:37
6F:→ coolcomm:这两篇对 CanBuildFrom只提到一句话啊=3= 04/05 01:06
7F:→ coolcomm:我最搞不懂的是编译器到底会去哪些地方抓implicit... 04/05 01:08
8F:→ firose:我最搞不懂scala编译器如何推导泛型参数 04/05 09:14
10F:→ coolcomm:楼上那篇感觉好可怕XD 04/06 01:52
11F:→ Chikei:因为implicit的来源有点多,所以在比优先权的时候有点长XD 04/06 02:00
12F:→ Chikei:只是要搞清楚可能来源的话就看前两段就好 04/06 02:01
14F:→ brianhsu:因为CanBuildFrom就是Typeclass,所以一句就够了(逃 04/08 17:25