问题: 包含和添加ConcurrentSkipListSet(csls)的文档声明如下:
public boolean add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。更正式地,如果集合不包含e.equals(e2)的元素e2,则将指定的元素e添加到该集合。如果此set已包含该元素,则调用将保持set不变并返回false。
public boolean contains(Object o) 如果此set包含指定的元素,则返回true。更正式地说,当且仅当此集合包含o.equals(e)的元素e时才返回true。
但我没有看到这种行为。下面的代码(单元测试)揭示了这种差异。
@Test
public void testComparison() throws Exception {
ObjectKey key = new ObjectKey("a", "b")
MetricTimeDataContext entry1 = new MetricTimeDataContext(1l, "Count", 10, 0, key)
MetricTimeDataContext entry2 = new MetricTimeDataContext(1l, "Count", 10, null, key)
Assert.assertEquals(1, entry1 <=> entry2) // the compare shows entry1 > entry2
Assert.assertNotEquals(entry1, entry2) // entry != entry2
Assert.assertEquals(Boolean.FALSE, entry2.equals(entry1)) // EDIT: Added this since documentation states it is performing this test. this passes..
Assert.assertNotEquals(entry1.hashCode(), entry2.hashCode()) // hashcodes are diff
// this block shows correct functionality of ConcurrentHashMap
def final Map<MetricTimeDataContext, Boolean> store = new ConcurrentHashMap<>()
store.put(entry1, Boolean.TRUE)
Assert.assertFalse(store.containsKey(entry2)) // correct! since entry1 != entry2
store.put(entry2, Boolean.TRUE)
Assert.assertEquals(2, store.size()) // correct! 2 items added.
// this block shows INcorrect functionality of ConcurrentSkipListSet
def final Set<MetricTimeDataContext> dataStore = new ConcurrentSkipListSet<>()
Assert.assertTrue(dataStore.add(entry1))
Assert.assertFalse(dataStore.contains(entry2)) // <--- this line fails unit test. why ???
Assert.assertTrue(dataStore.add(entry2)) // <-- this line also fails if above line is absent
}
我错过了一些明显的东西吗?上面的条目(entry1,entry2)显然不相等,但我不能将它们都添加到csls中。是什么赋予了?
我需要使用Concurrent数据结构,因为此代码将用于分布式env(akka)。此外,MetricTimeDataContext实现了与上面的单元测试中所示的相似,并且具有适当的equals和hashcode实现。
感谢。
更新:[已解决] 所以感谢@mbs和@JasonC的推动,我在最顶层再增加了两个测试:
Assert.assertEquals(Boolean.FALSE,entry2.equals(entry1))//这传递(相等很好) Assert.assertEquals(-1,entry2&lt; =&gt; entry1)//这返回0而不是-1(comp被破坏)
所以我的比较算法不正确。
再次感谢。
Java:
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
Groovy的:
[INFO] \- org.codehaus.groovy:groovy-all:jar:2.1.5:compile
平台:
Linux ariel 3.5.0-43-generic #66~precise1-Ubuntu SMP Thu Oct 24 14:52:23 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
答案 0 :(得分:1)
很可能你的等号很好(因为ConcurrentHashMap很好)但是compareTo不匹配(因为ConcurrentSkipListMap是个问题)。我会在你的测试中检查compareTo和equals对于你正在使用的对象是否一致。
答案 1 :(得分:0)
我在发布后的几分钟内将此更新添加到我的原始帖子,因为SO不允许您回答8小时的问题。
所以我在最顶层再添加了两个测试:
Assert.assertEquals(-1, entry2 <=> entry1) // this returns 0 instead of -1
Assert.assertEquals(Boolean.FALSE, entry2.equals(entry1))
所以我的比较算法不正确。 @JasonC在发布此内容后约15分钟就打了这个。
此外,文档具有误导性,因为它明确指出添加取决于它不相等的等于。添加取决于compareTo,在我的情况下,entry2.compareTo(entry1)返回0而不是-1。
当然,最佳做法是使equals与compareTo逻辑匹配。
感谢所有回应。