【问题标题】:HashSet is adding duplicate StringsHashSet 正在添加重复的字符串
【发布时间】:2017-05-18 12:15:09
【问题描述】:

编辑 对不起,我在某个地方打错字了,当我重新阅读它大约 500 次时找不到它-.- 很抱歉浪费了您的时间,但感谢您的意见。

我的问题是,我不知何故在HashSet 中有"ghost"-elements

我有 2 HashSetsStrings(我们称它们为 AB),它们被填充在一个循环中。

之后,我想比较它们并得到一些奇怪的结果:

A.size() -> 54201
B.size() -> 54201

然后,我在我的集​​合上执行一些操作,例如删除和保留(所有操作都使用原始集合的副本完成):

A.removeAll(B).size() -> 48
B.removeAll(A).size() -> 0

这就是我开始怀疑的地方。如果没有重复,并且集合大小相同,那么差异怎么可能不一样呢?

A.retainAll(B).size() -> 54201
B.retainAll(A).size() -> 54201

似乎它们具有相同的元素和大小,但A 具有更多48 元素(?!?)

A.equals(B) -> false

当我将它们转换为数组时,发生了这种情况:

Object[] A_array = A.toArray()
Object[] B_array = B.toArray()

A_array.length -> 54249 // here is my difference of 48 elements
B_array.length -> 54201

有人知道这里发生了什么吗? 为什么数组中有48 元素似乎不在集合中?

感谢您的帮助,我真的没有想法。

编辑:

感谢您的 cmets,我将尝试说明更多详细信息和代码。至于 MVCE,我会尝试获得一个,但我不确定它是否可能。

情况是,我正在通过 IMAP 下载电子邮件,然后从标题中读取消息 ID。我为 2 个帐户执行此操作,然后我想比较它们是否有相同的消息。

所以,这是代码(因为我必须使用 jsps,它的 java 1.6):

Set<String> srcMsgIds = new HashSet<String>();
Set<String> dstMsgIds = new HashSet<String>();

Message[] srcMsgs = imap.searchInAllFolder(srcEmail); // download javax.mail.Message
for(Message m : srcMsgs) {
    IMAPMessage msg = (IMAPMessage) m;
    String rfc822msgid = msg.getMessageID();
    srcMsgIds.add(rfc822msgid.toLowerCase());
}

Message[] dstMsgs = imap.searchInAllFolder(destEmail);  // download javax.mail.Message
for(Message m : dstMsgs) {
    IMAPMessage msg = (IMAPMessage) m;
    String rfc822msgid = msg.getMessageID();
    dstMsgIds.add(rfc822msgid.toLowerCase());
}

int srcCount = new HashSet<String>(dstMsgIds).size(); // 54201
int dstCount = new HashSet<String>(dstMsgIds).size(); // 54201

Set<String> intersectionSrcDst = new HashSet<String>(srcMsgIds); // both in src and dst
intersectionSrcDst.retainAll(dstMsgIds);
int intersection1Count = intersectionSrcDst.size(); // 54201

Set<String> intersectionDstSrc = new HashSet<String>(dstMsgIds);
intersectionDstSrc.retainAll(srcMsgIds);
int intersection2Count = intersectionDstSrc.size(); // 54201

Set<String> srcNotDst = new HashSet<String>(srcMsgIds);
srcNotDst.removeAll(dstMsgIds);
int diff1Count = srcNotDst.size(); // 48

Set<String> dstNotSrc = new HashSet<String>(dstMsgIds);
dstNotSrc.removeAll(srcMsgIds);
int diff2Count = dstNotSrc.size(); // 0

Object[] srcArray = srcMsgIds.toArray();
Object[] dstArray = dstMsgIds.toArray();
int srcArrayLength = srcArray.length; // 54249
int dstArrayLength = dstArray.length; // 54201

再次感谢。

【问题讨论】:

  • 你为什么不提供minimal reproducible example我们可以执行并查看问题...?另外,请正确格式化您的代码。
  • 顺便说一句,您为什么要使用副本?
  • 您能否包含一个确实显示问题的mcve,否则答案将是not possible,或者不清楚。但也许是一个暗示。如果AB 确实包含您自己的类,您是否覆盖了hashCode
  • 你上面写的不准确。
  • 是的。这是最可能的解释。您的问题描述中的一个或多个事实/假设可能不正确。但除非您提供 MCVE,否则我们无法告诉您是哪一个。

标签: java set hashset


【解决方案1】:
How did you fill the sets ?
I try a very small piece of code without having these ghost effects.

HashSet<String> A = new HashSet<String>();
HashSet<String> B = new HashSet<String>();
    A.add("dog"); B.add("dog"); 
    A.add("cat"); B.add("cat"); 
    A.add("mouse"); B.add("mouse"); 
    A.add("dog"); B.add("dog"); 

    System.out.println("A is: " + A);
    System.out.println("B is: " + B);

   // A.removeAll(B); System.out.println("A size is: " + A.size()); 
   // A size is: 0
   // B.removeAll(A); System.out.println("B size is: " + B.size()); 
   // B size is: 0

// A.retainAll(B);  System.out.println("A size after retain is: "+A.size());
// A size after retain is: 3
// B.retainAll(A);  System.out.println("B size after retain is: "+B.size()); // B size after retain is: 3
   System.out.println("A == B ? :" + A.equals(B)); // A == B ? :true

【讨论】:

    【解决方案2】:

    当然,这是一个错字,我(和我的同事都没有)直到现在才找到它......

    对不起,谢谢你的光临

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多