Java 调用hashTable.get(key)时获取null

Java 调用hashTable.get(key)时获取null,java,hashtable,Java,Hashtable,我的项目中有Pair类,我在应用程序中使用hashtable。 在构建哈希表之后,我通过打印哈希表的内容来测试Pair对象是否被创建并正确存储在哈希表中,并且立即尝试使用get(key)方法获取其中一个值,它总是给我null 这是我的整个类,映射有一个hashtable类型的私有对象 包装元存储 import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.uti

我的项目中有Pair类,我在应用程序中使用hashtable。 在构建哈希表之后,我通过打印哈希表的内容来测试Pair对象是否被创建并正确存储在哈希表中,并且立即尝试使用get(key)方法获取其中一个值,它总是给我null

这是我的整个类,映射有一个hashtable类型的私有对象 包装元存储

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

谢谢

我需要看看您的Pair实现。我的猜测是您没有正确地实现equals和hashcode


[编辑]

考虑到您的Pair实现(摘自评论)

您确实缺少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;
}
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;
}
HashCode紧跟在套件后面。你应该理解和遵循


我需要看一下你的Pair的实现。我的猜测是您没有正确地实现equals和hashcode


[编辑]

考虑到您的Pair实现(摘自评论)

您确实缺少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;
}
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;
}
HashCode紧跟在套件后面。你应该理解和遵循


在类
对中重新定义
equals
hashcode

在类
对中重新定义
equals
hashcode
这是由于您没有重写类对中的equals和hashcode方法,或者至少它们没有被正确重写。 当您在哈希表上调用“get”时,哈希表将首先调用hashCode方法来查找其表中的条目。如果hashCode没有被正确重写,那么hashtable将找不到您的条目。 其次,当hashtable找到条目时,它将测试条目的键是否等于您提供的键(在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;
}
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;
}
最后,当您在哈希表(更一般地说,在映射上)上迭代时,不应该调用键和do a get(键),而是应该直接在条目上迭代

for(Entry<K,V> e: map.entrySet()) {
   System.err.println(e.getKey+" is mapped to "+e.getValue());
}
for(条目e:map.entrySet()){
System.err.println(e.getKey+”映射到“+e.getValue());
}

它的效率更高,因为它不会调用hashCode和equals方法(如上所述),这可能是代价高昂的操作。

这是因为您没有重写类对中的equals和hashCode方法,或者至少没有正确重写它们。 当您在哈希表上调用“get”时,哈希表将首先调用hashCode方法来查找其表中的条目。如果hashCode没有被正确重写,那么hashtable将找不到您的条目。 其次,当hashtable找到条目时,它将测试条目的键是否等于您提供的键(在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;
}
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;
}
最后,当您在哈希表(更一般地说,在映射上)上迭代时,不应该调用键和do a get(键),而是应该直接在条目上迭代

for(Entry<K,V> e: map.entrySet()) {
   System.err.println(e.getKey+" is mapped to "+e.getValue());
}
for(条目e:map.entrySet()){
System.err.println(e.getKey+”映射到“+e.getValue());
}

它的效率更高,因为它不会调用hashCode和equals方法(如上所述),这可能是代价高昂的操作。

我认为看到
Pair
的实现会有所帮助。您是否实现了
hashCode
equals
?我认为看到
Pair
的实现会有所帮助。您是否实现了
hashCode
equals
?包预处理查询;公共类对{private String table;private String col;公共对(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 getCol(){return col public void setCol{this.col=col;}@Override public String to String(){return“[table=“+table+”,col=“+col+”]”];}不要在注释中粘贴代码,它不起作用…但是看起来,实际上,您并没有在
对中覆盖
hashCode
equals
。所以这就是您必须做的。我无法编辑原始问题,但我将您的代码放在答案中,并讨论了缺少的元素;公共类对{private String table;private String col;公共对(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 getCol(){return col public void setCol{this.col=col;}@Override public String to String(){return“[table=“+table+”,col=“+col+”];}}}不要在注释中粘贴代码,它不起作用……但是