Java 设置存储的重复记录

Java 设置存储的重复记录,java,collections,set,Java,Collections,Set,好的,这可能是一个简单的问题,但当我读到关于set和我得到的回复时,我感到困惑 我正在从数据库中获取重复记录,并使用set仅存储一条记录以满足一个条件(代码),从而忽略剩余的重复记录 Set<DiagnosisInfo> diagnosisInfoSet = patientDiagnosisHistoryRepository .findBydiagnosisdesc(UUID.fromString(patientID.toUpperCase()

好的,这可能是一个简单的问题,但当我读到关于set和我得到的回复时,我感到困惑

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

Set<DiagnosisInfo> diagnosisInfoSet = patientDiagnosisHistoryRepository
                    .findBydiagnosisdesc(UUID.fromString(patientID.toUpperCase()));
正如我们所见,相同的诊断代码记录显示多次,尽管它们重复。我想看到的回应如下

 "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"
    }
  ]

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

是的,当DiagnosisInfo不覆盖Equals和haschCode时,您会得到这样的结果

您的集合不知道如何检查此对象

{
  "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
,那么

/**
 * 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;
}
/**
*如果指定的元素尚未存在,则将其添加到此集合。
*更正式地说,如果
*此集合不包含元素e2,因此
*(e==null?e2==null:e.equals(e2))。
*如果此集合已经包含该元素,则调用将离开该集合
*未更改并返回false。
*
*@param e要添加到此集合的元素
*@如果此集合尚未包含指定的
*元素
*/
公共布尔加法(E){
返回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;
}
final V putVal(int散列,K键,V值,仅布尔值),
布尔逐出){
节点[]选项卡;节点p;int n,i;
如果((制表符=表格)=null | |(n=制表符长度)==0)
n=(tab=resize())。长度;
if((p=tab[i=(n-1)&hash])==null)
tab[i]=newNode(散列、键、值、null);
否则{
节点e;K;
if(p.hash==hash&&
((k=p.key)==key | |(key!=null&&key.equals(k)))
e=p;
else if(树节点的p实例)
e=((TreeNode)p).putTreeVal(this,tab,hash,key,value);
否则{
对于(int-binCount=0;;++binCount){
如果((e=p.next)==null){
p、 next=newNode(散列、键、值、null);
如果(binCount>=TREEIFY_阈值-1)/-1为第一个
treeifyBin(选项卡,哈希);
打破
}
如果(e.hash==hash&&
((k=e.key)==key | |(key!=null&&key.equals(k)))
打破
p=e;
}
}
如果(e!=null){//键的现有映射
V oldValue=e.value;
如果(!onlyFabSent | | oldValue==null)
e、 价值=价值;
节点接入后(e);
返回旧值;
}
}
++modCount;
如果(++大小>阈值)
调整大小();
节点插入后(逐出);
返回null;
}
重点是:

正如我们所见,相同的诊断代码记录显示多次,尽管它们重复

不,它们不一样。您必须为您的类诊断信息实现适当的equals()hashCode()方法

以确定两个对象“相同”;Set实现将使用这些对象提供的equals方法。最可能的情况是,您要么忘记在类中@Override equals();您提供的实现会导致
错误
;即使对于那些你认为“相同”的对象

有关更多详细信息,请参阅

考虑到您最近的评论,您的逻辑似乎仍然是向后的。您仍然认为您“知道”哪些对象是重复的,哪些不是。但是你的想法并不重要。唯一重要的是equals()方法中的实现。该操作的结果决定对象是否相等/相似;或者如果它们不同

因此:当您向类添加新字段时;并使用IDE重新生成这些方法,现在您对结果“不满意”;那么您的问题是,在生成过程中,包含了实际上认为“不重要”的字段。代码执行您让它执行的操作

因此,真实的回答如下:

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

感谢您的澄清。我完全忘记了我们必须重写equals和hashCode方法来比较两个对象的基本原理。我已经重写了hashCode和equals方法,昨天它运行良好,没有重复。今天,我在类中添加了几个字段,生成了hashCode和Equals方法,但它不起作用。我遗漏了什么?我是从Eclipse生成这些方法的。谢谢您的时间。我对你的两个否定问题投了赞成票。问题是我的需求改变了,我必须向类中添加几个字段,并重新生成hashCode和Equal方法。根据你更新的答案,我得到了它,好像它不支持我以后更新它一样。对吗?如果它不支持,那么如何控制这些重复记录?我是否必须编写手动hashCode和equals方法,而不是通过IDE生成它们?关键是
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;
}