设置存储的重复记录

时间:2017-02-13 17:18:56

标签: java collections set

好的,这可能是一个简单的问题,但当我读到关于集合和我得到的响应时,我很困惑。

我从数据库中获取重复记录,并使用set仅存储一个条件(代码)的一条记录,以忽略剩余的重复记录。

Set<DiagnosisInfo> diagnosisInfoSet = patientDiagnosisHistoryRepository
                    .findBydiagnosisdesc(UUID.fromString(patientID.toUpperCase()));

我得到的回应是

 "diagnosisInfo": [
    {
      "diagnosisCode": "T49.1X6S",
      "diagnosisCodeDescription": "Underdosing of antipruritics, sequela"
    },
    {
      "diagnosisCode": "T49.1X6S",
      "diagnosisCodeDescription": "Underdosing of antipruritics, sequela"
    },
    {
      "diagnosisCode": "T49.1X6S",
      "diagnosisCodeDescription": "Underdosing of antipruritics, sequela"
    },
    {
      "diagnosisCode": "T49.1X6S",
      "diagnosisCodeDescription": "Underdosing of antipruritics, sequela"
    },
    {
      "diagnosisCode": "V09.20",
      "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
    },
    {
      "diagnosisCode": "V09.20",
      "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
    },
    {
      "diagnosisCode": "V09.20",
      "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    }
  ]

我们可以看到相同的诊断代码记录虽然重复,但会多次显示。我想看到的回复是

 "diagnosisInfo": [
    {
      "diagnosisCode": "T49.1X6S",
      "diagnosisCodeDescription": "Underdosing of antipruritics, sequela"
    },
    {
      "diagnosisCode": "V09.20",
      "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
    },
    {
      "diagnosisCode": "E09.8",
      "diagnosisCodeDescription": "Drug or chemical induced diabetes mellitus with unspecified complications"
    }
  ]

一个代码的一个响应。我不知道是否必须更改我的查询,或者有关设置的内容。

2 个答案:

答案 0 :(得分:1)

是的,这是在DiagnosisInfo不覆盖Equals和haschCode

时获得的

您的Set无法知道如何检查此对象

{
  "diagnosisCode": "V09.20",
  "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
},

和这一个

{
  "diagnosisCode": "V09.20",
  "diagnosisCodeDescription": "Pedestrian injured in traffic accident involving unspecified motor vehicles*"
},

是一样的......

假设您调用的方法实现了HashSet<E>,那么spource代码:

/**
 * Adds the specified element to this set if it is not already present.
 * More formally, adds the specified element <tt>e</tt> to this set if
 * this set contains no element <tt>e2</tt> such that
 * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
 * If this set already contains the element, the call leaves the set
 * unchanged and returns <tt>false</tt>.
 *
 * @param e element to be added to this set
 * @return <tt>true</tt> if this set did not already contain the specified
 * element
 */
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

其中map.put调用 putVal

和putval使用equals和hashcode ...哈!

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
        if (p.hash == hash &&
            ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                        treeifyBin(tab, hash);
                    break;
                }
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;
                p = e;
            }
        }
        if (e != null) { // existing mapping for key
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
        }
    }
    ++modCount;
    if (++size > threshold)
        resize();
    afterNodeInsertion(evict);
    return null;
}

答案 1 :(得分:1)

重点是:

我们可以看到相同的诊断代码记录虽然重复,但会多次显示。

不,他们相同。您必须为您的类DiagnosisInfo实现正确的 equals() hashCode()方法!

为了确定两个物体是“相同的”; Set实现将使用这些对象提供的equals方法。而且最有可能的是,你要么在课堂上忘记了@Override equals();您提供的结果为false;即使是那些你认为“相同”的物品。

有关详细信息,请参阅here

鉴于您的最新评论,您似乎仍然有逻辑向后。你仍然认为你“知道”哪些对象是重复的,哪些不是。但你认为的重要性。唯一重要的是在equals()方法中实现。 操作的结果确定对象是否相等/相似;或者如果它们不同。

所以:当你向一个类添加新字段时;并使用您的IDE重新生成这些方法,现在您对结果“不满意”;那么你的问题是你在生成过程中包含字段,你实际上认为“应该没关系”。代码执行告诉要执行的操作。

因此,真实在这里回答:

  • 您应该退后一步,重新考虑您的对象模型。在生成equals / hashCode方法时,您不创建/添加字段并包含(或不包括)它们,因为可以执行此操作。不,你决定要做什么需要;然后你实现了那个。
  • 然后:这样的代码完美用于单元测试和TDD。你不要等待阅读一些真实的数据; nope:您有各种单元测试,验证您的equals实现可以提供预期的结果。然后,当您添加新内容或更改代码时,您会重新运行这些测试,并告诉您有关已损坏的内容。