hashTable.get(key)を呼び出すとnullが返される

私は私のプロジェクトでPairクラスを持っていて、私のアプリケーションでハッシュテーブルを使っています。 私のハッシュテーブルを構築した後、ペアオブジェクトが作成され、ハッシュの内容を印刷してハッシュテーブルに正しく格納されていることをテストし、すぐにget(key)メソッドを使って値の1つを取得しようとしています。私はnullです。

これは、私のクラス全体で、型ハッシュテーブルのプライベートオブジェクトを持つマッピングです。     パッケージメタストア;

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 hashTable ;

public Mapping(){
    hashTable= new Hashtable();
}


public Hashtable getHashTable() {
    return hashTable;
}


public void setHashTable(Hashtable hashTable) {
    this.hashTable = hashTable;
}


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

public void print() {
    Enumeration 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]}

ありがとう

0
私は、ペアの実装を見ることが役立つと思います。 hashCode equals を実装しましたか?
追加された 著者 hage,

3 答え

あなたのペアの実装を確認する必要があります。私の推測では、equalsとhashcodeを正しく実装していないということです。


[編集]

Pairの実装を考えると(コメントから抜粋して)

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

あなたは本当に等しくないとハッシュコードです。 背景:Object.equalsとObject.hashCodeのデフォルトの実装は、オブジェクトのメモリアドレス(Object reference)に基づいています。その観点から、すべてのペアは異なるオブジェクトであるため、すべてが異なります。

コレクションの実装が正しく機能するためには、コレクションに格納されるオブジェクトの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はスイートに従います。 一般Hashcodeの契約

@Override
public int hashCode() {
    int hash = this.table==null?0:table.hashCode();
    hash += 41 * this.col==null?0:col.hashCode();
    return hash;
 }
4
追加された
コメントにコードを貼り付けてはいけませんが、うまくいきませんが、 Pairで hashCode equals をオーバーライドしていないようですクラスを作成します。それであなたは何をしなければならないのですか。
追加された 著者 Jesper,
私は元の質問を編集することはできませんが、私はあなたのコードを答えに入れ、不足している要素について議論しました。
追加された 著者 maasg,
パッケージ前処理クエリ。パブリッククラスペア{プライベートStringテーブル。プライベートString col; publicペア(Stringテーブル、String col){super();} this.table = table; this.col = col; } public String getTable(){テーブルを返します。 }パブリックvoid setTable(文字列テーブル){this.table =テーブル; } public String getCol(){return col; } public void setCol(String col){this.col = col; } @Override public String toString(){return "[table =" + table + "、col =" + col + "]"; }}
追加された 著者 user1192027,

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

最後に、Hashtable(さらに一般的にはマップ上)を反復処理するときは、キーを呼び出してget(キー)を実行しないでください。代わりに、Entriesを直接反復処理する必要があります

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

これは、コストのかかる操作であるhashCodeメソッドとequalsメソッド(前述)を呼び出さないため、はるかに効率的です。

1
追加された
どうもありがとう、私はあなたのソリューションを試し、それが動作するかどうかを伝えます。 :)
追加された 著者 user1192027,

ペアクラスで equals hashcode を再定義します。

0
追加された
非常にありがとう、ありがとう:)
追加された 著者 user1192027,