[英]Retrieving value from key/value in ArrayList HashMap<String, String>
[英]Java generics Pair<String, String> stored in HashMap not retrieving key->value properly
這是Pair.java
import java.lang.*;
import java.util.*;
public class Pair<TYPEA, TYPEB> implements Comparable< Pair<TYPEA, TYPEB> > {
protected final TYPEA Key_;
protected final TYPEB Value_;
public Pair(TYPEA key, TYPEB value) {
Key_ = key;
Value_ = value;
}
public TYPEA getKey() {
return Key_;
}
public TYPEB getValue() {
return Value_;
}
public String toString() {
System.out.println("in toString()");
StringBuffer buff = new StringBuffer();
buff.append("Key: ");
buff.append(Key_);
buff.append("\tValue: ");
buff.append(Value_);
return(buff.toString() );
}
public int compareTo( Pair<TYPEA, TYPEB> p1 ) {
System.out.println("in compareTo()");
if ( null != p1 ) {
if ( p1.equals(this) ) {
return 0;
} else if ( p1.hashCode() > this.hashCode() ) {
return 1;
} else if ( p1.hashCode() < this.hashCode() ) {
return -1;
}
}
return(-1);
}
public boolean equals( Pair<TYPEA, TYPEB> p1 ) {
System.out.println("in equals()");
if ( null != p1 ) {
if ( p1.Key_.equals( this.Key_ ) && p1.Value_.equals( this.Value_ ) ) {
return(true);
}
}
return(false);
}
public int hashCode() {
int hashCode = Key_.hashCode() + (31 * Value_.hashCode());
System.out.println("in hashCode() [" + Integer.toString(hashCode) + "]");
return(hashCode);
}
}
這是測試用例:
import java.lang.*;
import java.util.*;
import junit.framework.*;
public class PairTest extends TestCase {
public void testPair() {
String key = new String("key");
String value = new String("asdf");
Pair<String, String> pair = new Pair<String, String>( key, value );
assertTrue( pair.getKey().equals( key ) );
assertTrue( pair.getValue().equals( value ) );
assertTrue( pair.equals( new Pair<String, String>(key, value)) );
}
public void testPairCollection() {
HashMap< Pair<String, String>, String> hm1 = new HashMap<Pair<String,String>, String>();
Pair<String, String> p1 = new Pair<String, String>("Test1", "Value1");
hm1.put(p1, "ONE");
Pair<String, String> p2 = new Pair<String, String>("Test1", "Value2");
hm1.put(p2, "TWO");
Pair<String, String> p3 = new Pair<String, String>("Test2", "Value1");
hm1.put(p3, "THREE");
Pair<String, String> p4 = new Pair<String, String>("Test2", "Value2");
hm1.put(p4, "FOUR");
Pair<String, String> p5 = new Pair<String, String>("Test3", "Value1");
hm1.put(p5, "FIVE");
Pair<String, String> p6 = new Pair<String, String>("Test3", "Value2");
hm1.put(p6, "SIX");
Pair<String, String> p7 = new Pair<String, String>("Test3", "Value3");
hm1.put(p7, "SEVEN");
assertTrue( hm1.size() == 7 );
Pair<String, String> pSrch = new Pair<String, String>("Test3", "Value3");
assertTrue( p7.equals(pSrch) );
assertTrue( pSrch.equals(p7) );
assertTrue( p7.hashCode() == pSrch.hashCode() );
assertTrue( 0 == p7.compareTo( pSrch ) );
assertTrue( 0 == pSrch.compareTo(p7) );
System.out.println("starting containsKey search");
assertTrue( hm1.containsKey( p7 ) );
System.out.println("starting containsKey search2");
assertTrue( hm1.containsKey( pSrch ) );
System.out.println("finishing containsKey search");
String result = hm1.get( pSrch );
assertTrue( null != result );
assertTrue( 0 == result.compareTo("SEVEN"));
}
}
這是我的問題,最后一個hm1.containsKey調用應該(我天真地期望)返回存儲的值,其中Pair <“Three”,“Three”>為真 - 我應該得到一個值為“SEVEN”的字符串。 這是輸出:
Running in equals()
in hashCode() [1976956095]
in hashCode() [1976956126]
in hashCode() [1976956096]
in hashCode() [1976956127]
in hashCode() [1976956097]
in hashCode() [1976956128]
in hashCode() [1976956159]
in equals()
in equals()
in hashCode() [1976956159]
in hashCode() [1976956159]
in compareTo()
in equals()
in compareTo()
in equals()
starting containsKey search
in hashCode() [1976956159]
starting containsKey search2
in hashCode() [1976956159] <--- Bug here?
Never reaches
String result = hm1.get( pSrch );
那么p7.hashCode()和pSrch.hashCode()是相等的,p7.equals(pSrch)和pSrch.equals(p7),以及hm1.containsValue(p7)== true,我希望hm1.containsValue(pSrch) )也會返回true,但事實並非如此。 我錯過了什么?
您需要從java.lang.Object
類重寫 equals
方法。
取而代之的是,你已經超負荷的附加版本,需要一個方法Pair
。 永遠不會被稱為完全不同的方法。 用這樣的東西代替你的equals
:
@Override
public boolean equals(Object o) {
System.out.println("in equals()");
if (o instanceof Pair) {
Pair<?, ?> p1 = (Pair<?, ?>) o;
if ( p1.Key_.equals( this.Key_ ) && p1.Value_.equals( this.Value_ ) ) {
return(true);
}
}
return(false);
}
要避免這種錯誤,請對要作為覆蓋的方法使用@Override
注釋。 如果沒有,您將收到編譯時錯誤。
您應該注意到在“啟動containsKey search2”之后它不會打印“in equals()”。 您也可以調試HashMap以查看.equals()方法被調用並返回false。 那是因為
public boolean equals( Pair<TYPEA, TYPEB> p1 )
不會覆蓋
public boolean equals(Object obj)
在java.lang.Object中定義
將您的代碼更改為
public boolean equals( Object obj ) {
if (!(obj instanceof Pair)) return false;
Pair p1 = (Pair) obj;
它的工作原理。 您可以通過在您認為重寫的方法之前放置@Override注釋來避免此類錯誤。 如果你實際上沒有覆蓋它,編譯器會告訴你。 這個
@Override public boolean equals( Pair<TYPEA, TYPEB> p1 )
導致編譯錯誤。 這個
@Override public boolean equals( Object obj )
才不是。 同樣好的IDE(例如Intellij IDEA)顯示覆蓋了哪些方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.