2009-12-09 40 views
4

这是我的用例,我有一个逻辑上等于我的HashMap键但不是相同的对象(不是==)的对象。我需要从HashMap中取出实体关键对象,以便我可以同步它。我知道我可以遍历ketSet,但与哈希相比,这是缓慢的。为什么getEntry(Object key)不公开在HashMap上?

通过java.util.HashMap实现,我看到了一个getEntry(Object key)方法,它正是我所需要的。任何想法为什么这没有被暴露?

你能想到任何其他方式我可以得到钥匙吗?

+0

你可以通过反思得到它,如果没有其他方法,仍然可以使用。 – Geo 2009-12-09 11:38:56

+0

逻辑上等于=等于方法被覆盖? HashMap始终使用equals而不是==。 通常不鼓励使用可变对象作为关键类。 – dmeister 2009-12-09 11:40:20

+0

@Geo:我会怀疑使用反射来获取同步对象;部分原因是由于性能上的担忧,但主要是因为非常量对象的显式同步无论如何都很难实现,不要介意何时通过反射来不透明地获取该引用。这很可能会很难理解,跟踪和调试,使维护成为一场噩梦。 – 2009-12-09 11:42:17

回答

4

我认为你会更好地在价值上增加额外的间接层。关键还应该是一个“纯粹”的价值。相反的:

Map<ReferenceObjectKey,Thing> map; 

用途:

Map<ValueObjectKey,ReferenceObject<Thing>> map; 
+0

这可能不一定是这里的问题 - 例如,字符串键仍然会导致上面声明的相同问题(除非你'实习所有的弦乐,这是一个坏主意];而我从来没有听过有人说弦是不合适的地图键。 – 2009-12-09 12:01:43

+0

我不关注。 'String's是我书中的值对象。 – 2009-12-09 12:34:21

+0

我在说这个问题仍然存在于字符串和其他值对象中;您提出的解决方案不能解决问题(因为querent构成的问题不是需要解决的问题)。 – 2009-12-09 14:11:53

0

这听起来像是一个更深层次的问题。你为什么需要这样的事情?为什么关键不是唯一的对象?

你是什么意思,“所以我可以同步它”?

+0

我怀疑希望什么是所有对同等对象的调用(即,将映射到散列映射中的同一个键*),以获得对同步的一致对象实例的访问。 querent没有说他为什么要这样做,但这听起来像是某种尝试阻止两个线程一次修改给定键的映射。 – 2009-12-09 11:52:33

+0

我认为你是对的。使用ConcurrentHashMap可以解决他的问题,如果关于该问题的假设是正确的,当然:) – 2009-12-09 12:15:27

3

我不能回答你真正的问题(为什么方法没有公开),而不是显而易见的,“因为作者决定不公开它。”

然而,你的问题使我相信你有一个相当奇怪的同步方案正在进行;从我的理解中,你只是试图调用它来获得用于同步的同等对象的规范表示。这听起来像一个非常糟糕的主意,正如我在对问题的评论中指出的那样。

更好的方法是重新考虑如何以及为什么要在这些关键对象上进行同步,并将同步更清晰,更好地完成,最好是在更高级别或完全使用替代方法。

如果你发布了一个你想要做这个同步的代码片段,这样其他人可以通过一个更清晰的方式来实现它,这可能会有所帮助。一个例子就是使用线程安全的地图类(如ConcurrentHashMap),如果这确实是你想要在这里实现的。

编辑:看看How To Ask Questions The Smart Way,特别是我已经链接的重点,因为这是一个经典的例子。看起来您的整体设计可能有点偏离,需要朝另一个方向发展;所以当你陷入这个特定的问题时,这是一个更大问题的症状。给我们更广泛的背景将导致你得到更好的整体答案。

-1

我很抱歉,但你似乎在这里有一个概念上的突破。

如果您的问题是您“等待”一个等效对象(.equals()为true,但==为false)到一个键,并且需要找到该键,那么使用get的Object变体将无济于事你,因为Object支持的唯一的.equals是identity(==)。

你需要做的是在你的关键类中实现equals()和hashcode()。

这将使它获得条目的微不足道。

+0

当然,我已经实现了equals和hashcode。我的问题说明 – 2009-12-12 17:54:57

2

实际上,来电者要求的方法将是有益的。这可能是一个错误,它或者类似的东西不包括在内。

正因为如此,假设你想增加这是一个从密钥“a”对应的整数值 - 你最终不得不做“一”两次哈希查找。假设您想区分不存在的值和存在的值,但将其映射到空值 - 再次是两个哈希查找。

在实践中,世界上还没有因为这样结束了,虽然。

1

最近我自己最近偶然发现了这个问题。当我把问题解决得足够的时候,我基本上使用了两种不同的方法将数据与用于确定相等性的关键对象的部分相关联。

  • 随着键映射到的值,经由地图
  • 与包含与密钥对象中的数据,但没有在.equals()/ hashCode方法中使用,通过组合物。

我在密钥类中使用List来确定相等和哈希码,并且其中有3个其他字段 - 一个布尔值和2个字符串。最后,我重拍的地图作为地图<列表<字符串> ...>和重构了其他3场到自己的类,然后有原始类的列表的组成和新类。我觉得在这之后代码看起来更好。

相关问题