2014-11-05 4 views
0

Iam, создающий метод java, который задает строку ключевых слов, возвращает HashMap. Ключ к HashMap - это объект типа subXMLdoc, который я назвал docpart. Вещественная часть HashMap является массивом объектов Term_with_Pos. Мое намерение состоит в том, чтобы группировать все объекты Term_with_Pos под тем же объектом «docpart». Мой вопрос, почему в том, что, следующее логическое выражение всегда равно ИСТИНАHashMap.containKey возвращает неправильное значение

  (ans.containsKey(docpart)== false) 

SEE метод ниже:

public static void termProximity (String qry, HashMap<subXMLdoc, 
           ArrayList<Term_with_Pos>> ans 
                ) throws SQLException 
    { 
     // convert the string of keywords (qry) into a list of terms (query) 
     ArrayList<Term_with_Pos> query = convertQuery(qry); 
     for (int i=0; i<query.size(); i++){ 
      ResultSet rs = DbaseManager.displayFreqTb2 (con, query.get(i).getTerm()); 
      while (rs.next()){ 
      //create the xml element object. 
      //This will serve as the key to the HashMap 
      subXMLdoc docpart = new subXMLdoc (  rs.getString("docId"), 
               rs.getInt("eTypeId") , 
               rs.getString("dewId")) ; 
      //create a term with position object 
      Term_with_Pos trm = new Term_with_Pos(); 
      trm.setTerm(rs.getString("trm")); 
     // trm.setPosition(rs.getInt("pos")); 
     trm.setPosition(0); 

     if (ans.containsKey(docpart)==false){ 
      ArrayList<Term_with_Pos> postings = new ArrayList<>(); 
      postings.add(0,trm); 
      ans.put(docpart,postings); 
     } else{ 
      ArrayList<Term_with_Pos> postings = ans.get(docpart); 
      int psize = postings.size(); 
      postings.add(psize,trm); 
      ans.put(docpart,postings); 
     } 
     } // while 
    rs.close(); 
    } // for 
    } // termProximity 

Я уже переопределения равный метод, как показано в следующем классе.

public class subXMLdoc { 
     private String docId ; 
     private int elmTypeId;  
     private String dewId ; 

     public subXMLdoc (String dcId, int nodeId, String dew){ 
     docId = dcId; 
     elmTypeId = nodeId ;  
     dewId = dew ; 
     } 

     public int getNodeId(){ return elmTypeId;} 
     public String getDew(){ return dewId;} 
     public String getDocId(){ return docId;} 


     @Override 
     public boolean equals(Object o){ 
     if(!(o instanceof subXMLdoc)) 
      return false; 
     subXMLdoc q = (subXMLdoc)o; 
     return (this.docId.equals(q.getDocId()) 
        && (this.elmTypeId == q.getNodeId()) && (this.dewId.equals(q.getDew())));   
     }//equals 
    } 

Пожалуйста, помогите мне определить, почему и как решить проблему.

Для строки qry = "monica lewinsky". Метод возвращает следующую процедуру вывода две колонки: Первый столбец является ключом HashMap в то время как второй столбец значение часть HashMap

 (3000, 11, 0.00.03.00.02.00)  (monica, 0) 
     (1518000, 24, 0.00.03.02.00)  (monica, 0) 
     (724000, 11, 0.00.03.00.13.00)  (monica, 0) 
     (1360000, 11, 0.00.03.00.10.00) (monica, 0) 
     (3000, 11, 0.00.03.00.02.00)  (lewinsky, 0) 
     (1294000, 28, 0.00.03.01.01)  (monica, 0) 
     (420000, 24, 0.00.03.02.00)  (monica, 0) 
     (976000, 28, 0.00.03.02.06)  (monica, 0) 
     (1374000, 11, 0.00.03.00.31.00) (monica, 0) 
     (1360000, 12, 0.00.03.00.16.01) (monica, 0) 
     (1360000, 11, 0.00.03.00.16.00) (monica, 0) 

Обратите внимание, что линии 1 и линии 5 имеют тот же ключ (3000, 11 , 0.00.03.00.02.00), т.е. docpart, и поэтому его необходимо объединить в единицу. Таким образом, выход предполагают, чтобы быть

  (3000, 11, 0.00.03.00.02.00)  (monica, 0), (lewinsky, 0) 
      (1518000, 24, 0.00.03.02.00)  (monica, 0) 
      (724000, 11, 0.00.03.00.13.00)  (monica, 0) 
      (1360000, 11, 0.00.03.00.10.00) (monica, 0) 
      (1294000, 28, 0.00.03.01.01)  (monica, 0) 
      (420000, 24, 0.00.03.02.00)   (monica, 0) 
      (976000, 28, 0.00.03.02.06)   (monica, 0) 
      (1374000, 11, 0.00.03.00.31.00) (monica, 0) 
      (1360000, 12, 0.00.03.00.16.01) (monica, 0) 
      (1360000, 11, 0.00.03.00.16.00) (monica, 0) 
+2

'HashMap' работает с' hashCode' объекта, вы нарушили контракт 'equals' /' hashCode'. – MadProgrammer

ответ

1

Вы состояние:

Я уже переопределения равный метод, как показано в следующем классе.

Необходимо также переопределить hashCode, особенно для ключа HashMap. Где вы это делаете?

Ваш хэш-код должен использовать те же поля, что равняется использования, а договор является то, что если два объекта равны, их hashCodes должны быть идентичными, но обратное не всегда верно - два объекта с тем же хэш-код может теоретически не равны.

Так что, если это ваш равно:

@Override 
    public boolean equals(Object o){ 
    if(!(o instanceof subXMLdoc)) 
     return false; 
    subXMLdoc q = (subXMLdoc)o; 
    return (this.docId.equals(q.getDocId()) 
       && (this.elmTypeId == q.getNodeId()) 
       && (this.dewId.equals(q.getDew())));   
    } 

Затем хэш-код должен использовать в DocId, в elmTypeIt и поля dewId вычислить его значение.


Например (я обманул), но это то, что Eclipse, дал мне для равных и хэш-код, и это имеет смысл, если вы об этом думаете:

@Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((dewId == null) ? 0 : dewId.hashCode()); 
     result = prime * result + ((docId == null) ? 0 : docId.hashCode()); 
     result = prime * result + elmTypeId; 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
     return true; 
     if (obj == null) 
     return false; 
     if (getClass() != obj.getClass()) 
     return false; 
     SubXmlDoc other = (SubXmlDoc) obj; 
     if (dewId == null) { 
     if (other.dewId != null) 
      return false; 
     } else if (!dewId.equals(other.dewId)) 
     return false; 
     if (docId == null) { 
     if (other.docId != null) 
      return false; 
     } else if (!docId.equals(other.docId)) 
     return false; 
     if (elmTypeId != other.elmTypeId) 
     return false; 
     return true; 
    } 

Как и в сторону, пожалуйста, обратите внимание также, что ваш код должен соответствовать соглашениям об именах Java, чтобы не обманывать других. Имена классов должны начинаться с буквы верхнего регистра, и все непостоянные имена должны использовать случай верблюда. Поэтому ваше имя класса должно быть "SubXmlDoc".

+0

Благодарим за быстрый ответ. Я хочу вычислить близость ключевых слов в заданном строковом значении. Как мне переопределить hashCode. – user3422243

+0

@ user3422243: см. Править для ответа. В примерах, которые я вижу, часто используются полномочия простых чисел, чтобы попытаться увеличить выделение ячеек. –

+0

@ user3422243: обратите внимание также, что ваш код должен соответствовать соглашениям об именах Java, чтобы избежать обмана других. Имена классов должны начинаться с буквы верхнего регистра, и все непостоянные имена должны использовать случай верблюда. Таким образом, ваше имя класса должно быть «SubXmlDoc». –

0

Вам необходимо переопределить метод hashCode() в вашем классе.HashMaphashCode вашего объекта. Вы должны переопределить как equals(), так и hashCode().

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