2012-02-06 2 views
0

У меня есть класс Pair в моем проекте, и я использую hashtable в своем приложении. После построения моей хэш-таблицы я проверяю, что объекты Pair создаются и сохраняются правильно в хеш-таблице, печатая содержимое хэша, и сразу же я пытаюсь получить одно из значений с помощью метода get (key), и это всегда дает мне null.Получение null при вызове hashTable.get (key)

Это мой весь класс, картография, которая имеет частный объект типа hashtable 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

ответ

4

я должен был бы увидеть вашу реализацию пары. Я предполагаю, что вы неправильно используете 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 по умолчанию основана на адресе памяти объекта (ссылка на объект). С этой точки зрения все ваши пары все разные, так как они разные объекты.

Для того, чтобы всякая реализация коллекции работала правильно, вам необходимо переопределить стандартную реализацию 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

пакет preprocessingQuery; public class Pair { \t приватный стол для струн; \t private String col; \t \t \t общественного пара (String таблица, строка столбец) { \t \t супер(); \t \t это.table = таблица; \t \t this.col = col; \t} \t public String getTable() { \t \t таблица обратного отсчета; \t} \t public void setTable (String table) { \t \t это.table = таблица; \t} \t public String getCol() { \t \t return col; \t} \t public void setCol (String col) { \t \t this.col = col; \t} \t \t @Override общественного Строка ToString() { \t \t возвращение "[таблица =" + стол + "столбец =" + цвет + "]"; \t} \t \t } – user1192027

+0

Не вставить код в комментариях, это не работает ... Но, похоже, на самом деле, вы не перекрывая '' hashCode' и equals' в своем классе 'Pair'. Вот что вам нужно сделать. – Jesper

+0

Я не могу отредактировать исходный вопрос, но я поставил ваш код в ответ и обсудил недостающие элементы. – maasg

0

Redefine equals и hashcode в классе Pair.

+0

Спасибо вам большое, это сработало :) – user1192027

1

Это связано с тем, что вы не переопределили методы equals и hashCode в классе Pair, или, по крайней мере, они не были должным образом переопределены. Когда вы вызываете «get» на хеш-таблице, хэш-таблица сначала вызывается методом 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 (ключ), но вместо того, чтобы , вы должны перебирать непосредственно над Заявок

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

это гораздо более эффективно, потому что это не будет вызывать хэш-код и равняется методов (как описано выше), которые могут быть дорогостоящие операции.

+0

Спасибо вам большое, я попробую ваши решения и скажу вам, если это сработает. :) – user1192027

Смежные вопросы