Is there any reason EnumMap and EnumSet are not Navigable
枚举是可比较的,这意味着您可以
1 2
| NavigableSet<AccessMode> modes = new TreeSet<>();
NavigableMap<AccessMode, Object> modeMap = new TreeMap<>(); |
它们有O(ln n)访问时间。
枚举集合具有O(1)访问时间,但不可导航。
1 2
| NavigableSet<AccessMode> modes = EnumSet.noneOf(AccessMode.class); // doesn't compile
NavigableMap<AccessMode, Object> modeMap = new EnumMap<>(AccessMode.class); // doesn't compile |
我想知道枚举集合不可导航(和排序)是否有原因。我是不是错过了什么?
- 旁注:EnumSet是一个抽象类。
- @谢谢你。我已经修正了那个例子。
- 查看实现,EnumSets(Regular和Jumbo)恰好按枚举的升序值排序。
- 我想这是因为enum是无序的:声明的顺序是在values上的foreach循环和其他什么循环上,但是由于您可以提供自己的值,所以这个顺序对于比较枚举值没有关系。
- @dasbinklenlightpublic class Enum> implements Comparable, Serializable。
- 它们的迭代器总是按元素或键的升序排列,这只会让我更好奇这个问题。;)
- @dasbinkenlight是有意义的,但当枚举扩展到可比的范围时,它有一个自然的顺序。
- 我的最佳猜测是navigability并没有被视为枚举集的主要用例。在实施过程中,没有任何东西会妨碍导航。
- 如果Enumset正在实现navigableset,那么问题是人们可能会尝试使用一种复杂而缓慢的迭代方式来迭代基本上是位向量的内容。它可能被认为既没用又没用。
- 但是@destroy navigability不是关于迭代吗?
- @反托罗伊有趣的一点。iterator()是它提供的功能之一。拥有更多的方法可能意味着使用的频率更高,但是如果您想要第一个()或最后一个(),则需要创建一个比集合内部所能做的效率更低的迭代器。
- @马尔可托普尼克什么会给Enumset带来适航性?那么,如何以一种合理而有用的方式实现子集方法呢?我的意思是使用基于枚举的类的好方法是使用枚举,而不是使用迭代器()或子集()等。
- @我认为这是最可能的解释。如果你需要它,总有一个树集合。
- @就像特雷塞特和特雷马普现在做的那样。
- 彼得,这正是我的想法。
- 您应该看到一个枚举表或哈希表是内部的,而不是访问它的方式。因为这些模式对于所有语言来说都是通用的,因为它们是有效的(快速和轻松)。在我看来,以不基于其固有效率的方式访问它们是没有意义的。在Enumset上使用子集可以转换为效率较低的类型,也可以为所有实例添加权重。
- @Destroy枚举本身并没有提供subSet、tailSet等的功能。您可能会需要它。但是,正如这里所说的,它看起来像是一个罕见的用例,没有得到Java库的支持。
- @正如你所说的,反托罗伊·埃努姆塞特既没有一点背景。我看不到像string对substring那样有多少开销。
- @马尔科托普尼克,如果你把你的评论作为答案,我会慷慨地接受。
- @彼得·劳里,你来了,但赏金真的不必要:)
- @markotopolinik还有97k的作用;)一旦超时,将在几个小时内增加赏金。
- 我能说什么,非常感谢:)
- 哇,50万块的赏金。我想只有从乔希·布洛克的那封邮件里挖出来的人才能得到这笔赏金。或者我,表明有这样一封电子邮件:—)
- 不完全是500,不是500千。
- 哈,不知道江户十一〔九〕是从哪里来的。我的眼睛都是$$
- @卢卡塞德,你真的需要奖励赏金。首先你要等两天。然后你可以提供赏金。然后你必须等24小时才能给它。如果你想再给一次赏金,那就得等上24个小时。但我也会为你做的。;)
JDK及其各种API中缺少许多"明显"的特性。为什么省略/忘记了这个特殊功能?我们只能猜测。但您的问题在Sun/Oracle已经存在很长一段时间了:
- http://bugs.sun.com/bugdatabase/view_bug.do?BugSyID=6278287
- http://www.java.net/node/644910
您可以通过评论来支持这些RFE。请注意,下面是Joshua Bloch对这个问题的权威回答:
I vaguely recall considering it, but I can't recall whether we
explicitly rejected it with good reason. We were running very low on
time when I implemented EnumSet and EnumMap, and it's possible that
time played a role in our decision
http://comments.gmane.org/gmane.comp.java.jsr.166-并发/2158
所以即使是他也不得不猜测:—)
- +1个很好的答案
- @彼得:我不得不承认,我在谷歌上发布了前4个链接中的3个,搜索"Enumset导航",第一个是你的问题;-)
- 嗯,我应该自己去谷歌搜索。;)
- 结果我们的第二次猜测相当准确。理想情况下,他们可以实现它,但这将花费更多的时间,并且会受到更多的错误和投诉。由于他们意识到可导航的用例被其他结构所覆盖,并且他们专门添加了这一个来阻止人们使用"或ed位字段"习惯用法,所以他们毫不担心地放弃了它。
- @彼得:但是,这让人们觉得,所以这是个好问题…
- 这是J.Bloch的一个奇怪的评论,因为Enummap/set在1.5中可用,1.6中引入了可导航的内容以适应Concurrentskiplistmap。在我看来,不进行Enummap/Set导航的主要原因是文书工作——也就是说,必须有人编写测试用例,而总体效益太小。旁注:我们可以通过二进制搜索找到上界,下面是迭代器。
- @ BestsSS,在"Java 6中的新内容"中引用的特定bug ID是在1998针对Java 1.2提出的。在开发EnumXxx的时候,他们可能非常熟悉NavigableXxx接口正在进行的工作,并且很容易决定在EnumXxx中实现它们。另外,如果您查看这个bug id,很明显NavigableXxx没有特定的与CSLM的密切链接。在书面工作上达成一致——必须保持对发布任何一行JDK代码所需工作的洞察力。
- @Marko,我很困惑,这个bug清楚地引用了TreeMap和TreeSet中实现的,以及新的ConcurrentsKiplist类,随着JSR166X的集成,驱动力是JSR166,它也提供了CSLM。
- @Besss是的,我的观点是,这是一个集成过程,在这个过程中,对SortedXxx和新的并发类的关注是一样多的。它的引入是为了满足所有的导航需求,而不是特别是CSLM。
- @Marko,看看g.oswego.edu/dl/concurrency-interest如何处理JDK6中出现的可导航集合(并发排序的映射和集合),当然,标准treemap应该是额外的优点的一部分。然而,我严重怀疑,如果JSR166没有发生,Treemap是否会获得导航权(RFE的投票数太少)。我不能确定,尽管2004-2006年我的个人历史非常黑暗,我也没有订阅JSR166。
- @BestSSS可导航集合绝对是JSR166的一部分。但是,适航性是否与并行结构特别相关?在我看来,适航性是一个正交的问题,恰好是DougLea关注的焦点,同时也是并发方面,可以说JSR166的要点。我想知道我在这个问题上是否错了,所以请分享这个方向的任何细节。
- (我可能会因为长时间的讨论而被踢到一边,而没有移动聊天-所以最后一条评论),导航在并发结构中很重要,因为它们不能原子地迭代(或解锁)。也许@tomhawtin可以插话,如果有人看到他-给他小费:d;或者我可以尝试在JSR166的邮件列表中询问。
- @BESTSSS:如果您在JSR-166邮件列表中找到答案,请确保为这个问题提供额外的答案!
我的最佳猜测是navigability并没有被视为枚举集的主要用例。在实施过程中,没有任何东西会妨碍导航。TreeSet和TreeMap涵盖了结合一组枚举成员和可导航性的罕见用例。
- 我有时依赖于EnumSet和EnumMap的迭代顺序(它有文档记录,所以我可以这样做)。我想至少声明我的变量为SortedSet或SortedMap,告诉读者我知道迭代顺序。我自己称之为值得考虑的用例。不要求你为所做的决定辩护。
这篇文章并没有直接回答这个问题,也没有试图回答这个问题,它只是传达了为什么引入了可导航性。
按要求发帖(太长了,无法发表评论)
The short answer is that Navigable exists because we didn't have
anything like upcoming"defenders" -- Sorted didn't describe all the
common functionality, and there was no way to do so except to
introduce a new interface. In practice, I'm sure"Sorted" is still
used much more often than"Navigable" as a declaration type, because
most people don't need the methods defined in Navigable but not
Sorted. Plus"Navigable" is just not a very nice name :-)
-Doug
- 哎呀。我想是时候发布一个新的Java版本了,扔掉所有的旧东西!-)
- 我暂时被java6和自己的后端卡住了。
- 这句话只解释了他们有一些新方法的方面,这些方法对于他们想要在接口中抽象的所有排序集合都是通用的。不幸的是,它仍然没有提供任何关于新方法是否对并发使用特别重要的洞察。