2012-02-06 144 views
0

時我得到了我的項目中的Pair類,我在我的應用程序中使用散列表。 在構造我的散列表之後,我測試了Pair對象被創建並通過打印散列的內容正確存儲在散列表中,並立即嘗試使用get(key)方法獲取其中一個值,並且它始終給我null。當我打電話給hashTable.get(鍵)

這是我的整個類,它有一個散列表類型的私人對象的映射 package metastore;

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.Hashtable; 
import java.util.StringTokenizer; 
import org.apache.hadoop.hive.ql.parse.ASTNode; 
import preprocessingQuery.Pair; 

public class Mapping { 
private Hashtable<Pair, Pair> hashTable ; 

public Mapping(){ 
    hashTable= new Hashtable<Pair, Pair>(); 
} 


public Hashtable<Pair, Pair> getHashTable() { 
    return hashTable; 
} 


public void setHashTable(Hashtable<Pair, Pair> hashTable) { 
    this.hashTable = hashTable; 
} 


public Pair getMapping(Pair originalPair) { 
    Pair mappedPair=(hashTable.get(originalPair)); 
    return mappedPair; 
} 
public ArrayList<Mapping> getPairs(ASTNode an){ 
    ArrayList<Mapping> pairs=new ArrayList<Mapping>(); 
    return pairs; 
} 

public void print() { 
    Enumeration<Pair> contentOfHT; 
    contentOfHT = hashTable.keys(); 
    while(contentOfHT.hasMoreElements()) { 
    Object str = contentOfHT.nextElement(); 
    System.out.println(str + "\tis mapped to " + 
      hashTable.get(str)); 
    } 
} 


public void loadMappingTable() { 
    String originalTable; 
    String originalCol; 
    String mappedTable; 
    String mappedCol; 
    Pair originalPair; 
    Pair mappedPair; 
    BufferedReader in = null; 

    try { 
     in = new BufferedReader(
       new FileReader(
         "D:\\Documents and Settings\\QUAdmin.STAFF\\Desktop\\mapping.txt")); 
     String line ; 
     while ((line = in.readLine()) != null) { 
      StringTokenizer stok = new StringTokenizer(line, "\t"); 
      originalTable= stok.nextToken(); 
      originalCol= stok.nextToken(); 
      mappedTable= stok.nextToken(); 
      mappedCol= stok.nextToken(); 
      originalPair=new Pair(originalTable,originalCol); 
      mappedPair=new Pair(mappedTable,mappedCol); 
      hashTable.put(originalPair, mappedPair); 

     } 
    } catch (Exception ex) { 
     // catch all exceptions as one. This is bad form imho 
     ex.printStackTrace(); 
    } finally { 
     try { 
      if (in != null) 
       in.close(); 
     } catch (IOException ex) { 
     } 
    } 
} 

public static void main(String[] args) 
{ 
    Mapping map=new Mapping(); 
    map.loadMappingTable(); 
    System.out.println("Size: "+ map.getHashTable().size()); 

    System.out.println("The content of the hash table"); 
    map.print(); 
    System.out.println("Testing the mapping"); 
    Pair originalPair=new Pair("table1","table1_name"); 
    System.out.println(map.getMapping(originalPair)); 
    System.out.println(map.getHashTable().get(originalPair)); 
    System.out.println(map.getHashTable()); 

} 
}//end of Mapping Class 

這是輸出

Size: 3 

The content of the hash table 

[table=table1, col=table1_age] is mapped to [table=table1_SNT, col=table1_SNT_age] 

[table=table1, col=table1_name] is mapped to [table=table1_SNT, col=table1_SNT_name] 

[table=table1, col=table1_id] is mapped to [table=table1_SNT, col=table1_SNT_id] 

Testing the mapping 

null 

null 

{[table=table1, col=table1_age]=[table=table1_SNT, col=table1_SNT_age], [table=table1, col=table1_name]=[table=table1_SNT, col=table1_SNT_name], [table=table1, col=table1_id]=[table=table1_SNT, col=table1_SNT_id]} 

感謝

+1

我認爲這會有助於看到'Pair'的實現。你實現了'hashCode'和'equals'嗎? – hage 2012-02-06 10:53:17

回答

4

我需要看到你的一雙翅膀實現。我的猜測是你沒有正確實現equals和hashcode。


[編輯]

鑑於你實現對(從註釋中獲取)

package preprocessingQuery; 
public class Pair { 
    private String table; 
    private String col; 
    public Pair(String table, String col) { 
     super(); 
     this.table = table; 
     this.col = col; 
    } 

    public String getTable() { 
     return table; 
    } 

    public void setTable(String table) { 
     this.table = table; 
    } 

    public String getCol() { 
     return col; 
    } 

    public void setCol(String col) { 
     this.col = col; 
    } 

    @Override public String toString() { 
     return "[table=" + table + ", col=" + col + "]"; 
    } 
} 

您確實丟失equals和hashCode。 一些背景:Object.equals和Object.hashCode的默認實現基於對象的內存地址(對象引用)。從這個角度來看,所有的對都是不同的,因爲它們是不同的對象。

要使任何集合實現正常工作,您需要覆蓋要存儲在集合中的對象的equals和hashCode的默認實現。

爲了您的Pair類,它應該是這個樣子:

@Override 
public boolean equals(Object other) { 
    if (this == other) { 
     return true; // shortcut for referential equality 
    } 
    if (other == null) { 
     return false; // by definition, 'this' object is not null 
    } 
    if (!(other instanceof Pair)) { 
     return false; 
    } 
    Pair otherPair = (Pair) other; // Cast to the known type 
    // check equality of the members 
    if (this.table == null) { 
     if (otherPair.table != null) { 
      return false; 
     } 
    } else if (!this.table.equals(otherPair.table)) { 
     return false; 
    } 
    if (this.col == null) { 
     if (otherPair.col != null) { 
      return false; 
     } 
    } else if (!this.col.equals(otherPair.col)) { 
     return false; 
    } 
    return true; 
} 

的hashCode如下套件。您應該瞭解並遵循the general contract of Hashcode

@Override 
public int hashCode() { 
    int hash = this.table==null?0:table.hashCode(); 
    hash += 41 * this.col==null?0:col.hashCode(); 
    return hash; 
} 
+0

package preprocessingQuery; public class Pair { \t private String table; \t private String col; \t \t \t公衆對(字符串表,字符串COL){ \t \t超級(); \t \t this.table = table; \t \t this.col = col; \t} \t public String getTable(){ \t \t return table; \t} \t public void setTable(String table){ \t \t this.table = table; \t} \t public String getCol(){ \t \t return col; \t} \t public void setCol(String col){ \t \t this.col = col; \t} \t @Override \t公共字符串的toString(){ \t \t返回 「[表=」 +表+ 「COL =」 + COL + 「]」; \t} \t \t } – user1192027 2012-02-06 11:15:10

+0

不要粘貼在評論代碼,這是行不通的。但是它看起來像,的確,你是不是覆蓋在你的'Pair'類'hashCode'和'equals'。所以這就是你必須要做的。 – Jesper 2012-02-06 13:05:09

+0

我無法編輯原始問題,但我在答案中放入了代碼並討論了缺失的元素。 – maasg 2012-02-06 17:35:47

0

重新定義equalshashcode在類Pair

+0

非常感謝你,它的工作:) – user1192027 2012-02-06 11:31:08

1

這是由於您沒有重寫類Pair中的equals和hashCode方法,或者至少它們沒有正確重寫。 當您在散列表上調用'get'時,散列表將首先調用hashCode方法在其表中查找條目。如果hashCode未被正確覆蓋,那麼hashtable將不會找到您的條目。 其次,當哈希表找到條目時,它會測試條目的關鍵字是否等於您提供的關鍵字(在發生hashCode衝突的情況下)。 可以覆蓋這些方法是這樣的:

public int hashCode { 
    return table.hashCode()+tableName.hashCode(); 
} 

public boolean equals(Object o) { 
    if (o==this) 
     return true; 
    if (o instanceof Pair) { 
     Pair p = (Pair) o; 
     return this.table.equals(p.table) && this.tableName.equals(p.tableName); 
    } 
    return false; 
} 

最後,當你遍歷一個哈希表(更通常,在一個地圖),你不應該調用鍵和做一個GET(鍵),而是,你應在報名

for(Entry<K,V> e: map.entrySet()) { 
    System.err.println(e.getKey+" is mapped to "+e.getValue()); 
} 

這是更有效,因爲這不會調用方法hashCode和equals(如上所述),這可能是昂貴的操作直接迭代。

+0

非常感謝你,我會嘗試你的解決方案,並告訴你它是否工作。 :) – user1192027 2012-02-06 11:17:50

相關問題