Translate-CS 板


LINE

原文网址:http://www.javacodegeeks.com/2013/03/java-collections-api-quirks.html 译文网址:http://blog.dontcareabout.us/2013/03/java-collection-api.html 感谢 tkcn 在 Java 技术上的协助。 BBS 版用 markdown 语法撰写 ______________________________________________________________________ 在提到 Java Collection API 时,我们会认为已经了解全部的东西了, 像是 [List]、[Set]、[Map]、[Iterable]、[Iterator]。 我们已经准备好 [补强 Java8 的 Collection API][enhance API]。 [List]: http://docs.oracle.com/javase/7/docs/api/java/util/List.html [Set]: http://docs.oracle.com/javase/7/docs/api/java/util/Set.html [Map]: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html [Iterable]: http://docs.oracle.com/javase/7/docs/api/java/lang/Iterable.html [Iterator]: http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html [enhance API]: http://cr.openjdk.java.net/~briangoetz/ lambda/collections-overview.html 但在那之後,每隔一段时间我们就会偶然发现这些奇怪的怪事, 来自於 JDK 深处、以及向下相容的遥远历史。 让我们来看一下这些不可修改(unmodifiable) 的 collection。 不可修改的 collection ------------------- 无论 collection 是否可以修改,都无法跟 collection API 作对应。 JDK 并没有 immutable 的 `List`、`Set`、`Collection` 的基础 type, 继承出来的就是 mutable 的 subtype。 所以下面这个 API 是不会出现在 JDK 当中的: // Immutable part of the Collection API public interface Collection { boolean contains(Object o); boolean containsAll(Collection<?> c); boolean isEmpty(); int size(); Object[] toArray(); <T> T[] toArray(T[] array); } // Mutable part of the Collection API public interface MutableCollection extends Collection { boolean add(E e); boolean addAll(Collection<? extends E> c); void clear(); boolean remove(Object o); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); } 有几个可能的原因解释为甚麽早期 Java 不这样实作。 最可能的原因是:不把 mutable 特性视为一个功能, 值得在 type 阶层当中占据一个 type。 所以,伴随而来的 [Collections] 这个 helper class 就会有一些好用的 method, 像是 `unmodifiableList()`、`unmodifiableSet()`、 `unmodifiableCollection()`...... 等等。 但是在使用不可修改的 collection 时要注意, [JavaDoc 中有一个非常奇怪的事情][quirk in JavaDoc]: 回传的 collection 并没有原本 collection 的 `hashCode()` 跟 `equals()`, 而是使用 `Object` 的 method。 当原本的 collection 是 set 或 list 时, 就需要 preserve the contract of these operation(译注:翻译不能 Orz)。 这句话讲的相当暧昧不明,它背後的原因是什麽? 在 [Stack Overflow] 有一个很棒的解释: 一个 `UnmodifiableList` 是一个 `UnmodifiableCollection`, 但是反过来说就不成立了。 一个包了 List 的 `UnmodifiableCollection` 并不是一个 `UnmodifiableList`。 所以如果你要比较一个包了 foo 这个 `List` 的 `UnmodifiableCollection`、 跟包了同样 `List` foo 的 `UnmodifiableList`, 这两个并不会相等。 如果你直接取得被 wrap 的 list,它们就会相等。 虽然这个推论是正确的,但是它的影响可能完全在意料之外。 [Collections]: http://docs.oracle.com/javase/7/docs/api/java/util/ Collections.html [quirk in JavaDoc]: http://docs.oracle.com/javase/7/docs/api/java/util/ Collections.html#unmodifiableCollection(java.util.Collection) [Stack Overflow]: http://stackoverflow.com/questions/ 12851229/hashcode-and-equals-for-collections-unmodifiablecollection/ 12851469#12851469 什麽叫底线... ------------- 底线就是你不可以倚赖 `Collections.equals()`。 虽然 `List.equals()` 跟 `Set.equals() 有良好定义, 但是不要信任 Collection.equals(),它的行为可能没有意义。 当你在 method signature 接了一个 collection 时请记得: public class MyClass { public void doStuff(Collection<?> collection) { // Don't rely on collection.equals() here! } } 译注 ---- 如果看不懂这篇在干麽,那容许我画蛇添足一下。 `Collections.unmodifiableCollection()` 的内容是: return new UnmodifiableCollection<T>(c); 而 `UnmodifiableCollection` 是实作 `Collection`, 其实是一个 delegate pattern: static class UnmodifiableCollection<E> implements Collection<E>, Serializable { final Collection<? extends E> c; UnmodifiableCollection(Collection<? extends E> c) { if (c==null) throw new NullPointerException(); this.c = c; } } 重点在於,`UnmodifiableCollection` 并没有实作 `hashCode()` 跟 `equals()`, 所以当你要一个 `UnmodifiableCollection` 作 `hashCode()` 时, 会直接使用 `Object` 的 `hashCode()`。 -- 钱锺书: 说出来的话 http://www.psmonkey.org 比不上不说出来的话 Java 版 cookcomic 版 只影射着说不出来的话 and more...... --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.25.13.90 ※ 编辑: PsMonkey 来自: 114.25.13.90 (03/22 15:59)







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Gossiping站内搜寻

TOP