HashMap.containsKey返回错误的值

时间:2014-11-05 04:52:02

标签: java

我写一个给出一串关键字的java方法将返回一个HashMap。 HashMap的关键是subXMLdoc类型的对象,我称之为docpart。 HashMap的值部分是Term_with_Pos对象的数组列表。我的意图是 将所有Term_with_Pos对象分组到同一“docpart”对象下。我的问题是为什么 以下布尔表达式始终等于TRUE

          (ans.containsKey(docpart)== false)

请参阅以下方法:

    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

我已经覆盖了以下类中显示的equal方法。

    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 个答案:

答案 0 :(得分:1)

你说:

  

我已经覆盖了以下类中所示的equal方法。

您还需要覆盖hashCode,尤其是HashMap的密钥。你在哪里这样做?

你的hashCode应该使用等于使用的相同字段,并且合同是如果两个对象相等,它们的hashCodes 必须相同,但反过来不一定是真的 - 两个对象理论上,相同的hashCode不能相等。

所以,如果这是你的平等:

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

然后hashCode必须使用docId,elmTypeIt和dewId字段来计算其值。


例如(我作弊)但这是Eclipse给我的equals和hashCode,如果你考虑它就有意义了:

   @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"

答案 1 :(得分:0)

您需要在班级中覆盖hashCode()方法。 HashMap使用您对象的hashCode。您必须在此处覆盖equals()hashCode()