簡體   English   中英

為什么hashTable包含冗余鍵

[英]Why hashTable contains redundant Keys

我對Hashtable有問題; 它包含冗余密鑰。 我已經重新定義了equal和hashcode,但是同樣的問題。 下面是我的問題的一個例子。 我真的需要幫助。 先感謝您。

public class Payoff {
    public ArrayList<Cluster> coalitions = new ArrayList<Cluster>();

    @Override
    public boolean equals(Object t) {
        // Vérification de la référence
        if (t==this)
            return true;
        //Vérification du type du paramètre puis de ses attributs.
        if (t instanceof Payoff) {
            Payoff tbis = (Payoff)t;
            return this.coalitions.equals(tbis.coalitions);
        } else
            return false;
    }

    @Override
    public int hashCode() {
        return this.coalitions.hashCode(); 
    }
}

public class Cluster implements Cloneable {
    public ArrayList<Integer> dataArray = new ArrayList<Integer>();
    public double[] ch;
    public double coalitionPayoff;

    public Cluster() {
    }

    public Cluster(Cluster obj) {
        this.ch = obj.ch;
        this.dataArray = (ArrayList<Integer>)obj.dataArray.clone();
        this.coalitionPayoff = obj.coalitionPayoff;
    }

    public boolean equals(Object T)
{   // Vérification de la référence
    if (T==this)
        return true;
    //Vérification du type du paramètre puis de ses attributs.
    if (T instanceof Cluster)
    {
        Cluster Tbis = (Cluster) T;
        return this.DataArray.equals(Tbis. DataArray) && Arrays.equals(this.Ch,Tbis.Ch)
                 && (this.CoalitionPayoff ==Tbis.CoalitionPayoff);

    } else
        return false;
}

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dataArray == null) ? 0 : dataArray.hashCode());
        //result = prime * result + (int) (coalitionPayoff ^ (coalitionPayoff >>> 32));
        result = prime * result + ((ch == null) ? 0 : ch.hashCode());
        return result;
    }

    public Cluster clone() {
        return new Cluster ();
    }
}

public static void main(String[] args) throws Exception {
    Hashtable<Payoff,Double> HashTab = new Hashtable<Payoff,Double>();
    Payoff Pay1 = new Payoff();
    Cluster Cluster1 = new Cluster();
    Cluster1.DataArray.addAll(java.util.Arrays.asList(1,2,3));
    double[] ary = {1.5};
    Cluster1.Ch=  ary;
    Pay1.Coalitions.add(Cluster1);
    Cluster1 = new Cluster();
    Cluster1.DataArray.addAll(java.util.Arrays.asList(4,5));
    double[] ary2 = {4.5};
    Cluster1.Ch=  ary2;
    Pay1.Coalitions.add(Cluster1);
    HashTab.put(Pay1, 0.5);

    Payoff Pay2 = new Payoff();
    Cluster Cluster2 = new Cluster();
    Cluster2.DataArray.addAll(java.util.Arrays.asList(1,2,3));
    double[] ary3 = {1.5};      Cluster2.Ch=  ary3;
    Pay2.Coalitions.add(Cluster2);
    Cluster2 = new Cluster();
    Cluster2.DataArray.addAll(java.util.Arrays.asList(4,5));
    double[] ary4 = {4.5};
    Cluster2.Ch=  ary4;
    Pay2.Coalitions.add(Cluster2);
   if(!HashTab.containsKey(Pay2)){
      HashTab.put(Pay2, 0.5);
    }
    System.out.println(HashTab.size());
}

這行是問題所在:

result = prime * result + ((ch == null) ? 0 : ch.hashCode()

這是數組的哈希碼,而不是數組內容的哈希碼,因此當您說:

double[] ary = {1.5};
double[] ary3 = {1.5};

除了其中包含相同的數據外,它是不同的。 確保使用內容而不是對象引用作為哈希碼。

當然,Java有一個解決方案:

result = prime * result + ((ch == null) ? 0 : Arrays.hashCode(ch)

更新

這是我用來解決該問題的測試代碼。 JUnit Rulez!

public class TestHashTable
{
    @Test
    public void testEmpty()
    {
        final Cluster c1 = new Cluster();
        final Cluster c2 = new Cluster();
        Assert.assertEquals(c1, c2);
        Assert.assertEquals(c1.hashCode(), c2.hashCode());
    }

    @Test
    public void testSame()
    {
        final Payoff pay1 = new Payoff();
        final Cluster cluster1 = new Cluster();
        cluster1.dataArray.addAll(java.util.Arrays.asList(1,2,3));
        pay1.coalitions.add(cluster1);

        Assert.assertEquals(pay1, pay1);
        Assert.assertEquals(pay1.hashCode(), pay1.hashCode());
    }   

    @Test
    public void testEquals()
    {
        final Payoff pay1 = new Payoff();
        final Cluster cluster1 = new Cluster();
        cluster1.dataArray.addAll(java.util.Arrays.asList(1,2,3));
        pay1.coalitions.add(cluster1);

        final Payoff pay2 = new Payoff();
        final Cluster cluster2 = new Cluster();
        cluster2.dataArray.addAll(java.util.Arrays.asList(1,2,3));
        pay2.coalitions.add(cluster2);

        Assert.assertEquals(cluster1, cluster2);
        Assert.assertEquals(pay1, pay2);

        Assert.assertEquals(cluster1.hashCode(), cluster2.hashCode());
        Assert.assertEquals(pay1.hashCode(), pay1.hashCode());
    }

    @Test
    public void testUseInMap()
    {
        final Payoff pay1 = new Payoff();
        final Cluster cluster1 = new Cluster();
        cluster1.dataArray.addAll(java.util.Arrays.asList(1,2,3));
        final double[] a1 = {1.5};
        cluster1.ch = a1;
        pay1.coalitions.add(cluster1);

        final Payoff pay2 = new Payoff();
        final Cluster cluster2 = new Cluster();
        final double[] a2 = {1.5};
        cluster2.ch = a2;
        cluster2.dataArray.addAll(java.util.Arrays.asList(1,2,3));
        pay2.coalitions.add(cluster2);

        final Map<Payoff, Double> map = new HashMap<Payoff, Double>();
        map.put(pay1, 1.0);
        map.put(pay2, 2.0);

        Assert.assertEquals(1, map.size());
        Assert.assertTrue(2.0 == map.get(pay1));
    }
}

Clusterequals方法返回false,因為this.ch.equals(tbis.ch)返回false。

array1.equals(array2)等於array1 == array2 ,因此,如果內容相同但實際數組實例不同,則該方法將返回false。 要檢查數組而不是數組實例的內容,請使用Arrays.equals(array1,array2) (或者在您的情況下: Arrays.equals(this.ch,tbis.ch) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM