2012-02-06 7 views
0

私のプロジェクトにPairクラスがあり、アプリケーションでハッシュテーブルを使用しています。 ハッシュテーブルを作成した後、ペアオブジェクトが作成され、ハッシュの内容を出力してハッシュテーブルに正しく格納されていることをテストし、直ちにget(key)メソッドを使用して値の1つを取得しようとしています。私にnullを与える。hashTable.get(key)を呼び出すとnullになる

これは私のクラス全体のマッピングであり、タイプハッシュテーブル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

「ペア」の実装を確認すると便利だと思います。 'hashCode'と' equals'を実装しましたか? – hage

答えて

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のデフォルトの実装をオーバーライドする必要があります。あなたのペアクラスの

が、それは次のようになります。

@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; 
} 

ハッシュコードは、スイートに従います。 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

パッケージpreprocessingQuery; public classペア{ \tプライベートStringテーブル。 \tプライベート文字列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

+0

は、コメント内のコードを貼り付けないでください、それは動作しません...しかし、それは確かに、あなたは 'Pair'クラスで' hashCode'と 'equals'をオーバーライドしていない、のように見えます。それであなたは何をしなければならないのですか。 – Jesper

+0

私は元の質問を編集することはできませんが、私は答えにあなたのコードを置き、不足している要素について議論しました。 – maasg

0

クラスPairequalshashcodeを再定義します。

+0

非常にありがとう、それは働いた:) – user1192027

1

これは、クラスPairのequalsメソッドとhashCodeメソッドをオーバーライドしていないか、少なくとも適切にオーバーライドされていないためです。 ハッシュテーブルで 'get'を呼び出すと、ハッシュテーブルは最初にhashCodeメソッドを呼び出してそのテーブル内のエントリを検索します。 hashCodeが適切にオーバーライドされない場合、ハッシュテーブルはエントリを検索しません。 第2に、ハッシュテーブルがエントリを見つけたら、エントリのキーがあなたが提供したものと等しいことをテストします(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()); 
} 

(上述したように)、これはハッシュコードを呼び出し、メソッドに等しくないので、それは、はるかに効率的である上に、直接反復すべきです。

+0

ありがとう、私はあなたのソリューションを試し、それが動作するかどうかを教えてくれます。 :) – user1192027

関連する問題