隨筆 - 4  文章 - 13  trackbacks - 0
          <2009年1月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          情景上這樣的:我有一個重寫了equals方法的類,該類源碼如下。然后用一程序將此類多次循環put到HashMap中去,但每次put到1500次左右時,就會出現NullPointerException。
            在map.put的方法中,會先去判斷put進去的對象是否已經存在于map中,判斷方法調用的就是該對象的重寫的equals方法,如果說我寫的equals有問題的話,為什么前1000多次左右不會出現問題而在最后出現問題呢?起初以為是放到HashMap中的對象太大會出現內存溢出,但并未出現outofmemory異常,用JProfiler進行監測時也發現和heap的使用也沒關系……有哪位兄弟幫我解釋一下……

            重寫了equals方法的類:
          public class myPolSchema {
              
          // @Field
              private String GrpContNo;
              
          private String GrpPolNo;

              
          public String getGrpContNo() {
                  
          return GrpContNo;
              }


              
          public void setGrpContNo(String aGrpContNo) {
                  GrpContNo 
          = aGrpContNo;
              }


              
          public String getGrpPolNo() {
                  
          return GrpPolNo;
              }


              
          public void setGrpPolNo(String aGrpPolNo) {
                  GrpPolNo 
          = aGrpPolNo;
              }


              
          public boolean equals(Object otherObject) {
                  
          if (this == otherObject)
                      
          return true;
                  
          if (otherObject == null)
                      
          return false;
                  
          if (getClass() != otherObject.getClass())
                      
          return false;
                  myPolSchema other 
          = (myPolSchema) otherObject;
                  
          return GrpContNo.equals(other.getGrpContNo())
                          
          && GrpPolNo.equals(other.getGrpPolNo());
              }

          }

          測試類:

          import java.util.* ;
          public class MultiThreading{
          // implements Runnable 
              Map m=Collections.synchronizedMap(new HashMap());
              
          //HashMap m=new HashMap();
              Hashtable t=new Hashtable();
              
          public myPolSchema polschema;
              
          public void run() 
              
          {
                  polschema
          =new myPolSchema();
                  m.put(polschema, 
          "UPDATE");
                  System.out.println(
          "put end at " + new Date());
              }

              
          public static void main(String[] args) throws Exception {
                  MultiThreading t
          =new MultiThreading();
                  
          for(int i=0;i<=25000;i++){
                      
          try{
                          t.run();
                          
          //Thread.sleep(100);
                      }

                      
          catch(Exception ex){
                          
          //在我本地測試時當運行大概1500左右次的時間就會拋出NullPointerException
                          System.out.println("i is: " + i);
                          
          throw ex;
                      }

                  }

              }


          }

          如果您有興趣,請下載這兩個類的源碼并實際測試:
          /Files/foxinsky/sourceCode.rar
          如果哪位兄臺有好的解決方案,請不吝賜教!
          posted on 2009-01-14 12:34 foxinsky 閱讀(1832) 評論(10)  編輯  收藏

          FeedBack:
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 12:54 銀河使者
          只1500次,不可能產生內存溢出異常,根據你的描述是拋出NullPointerException異常,這說明你引用了一個對象變量,但這個對象變量值為null,問題出在equals方法中,有可能出在下面的代碼中:

          myPolSchema other = (myPolSchema) otherObject;
          return GrpContNo.equals(other.getGrpContNo())
          && GrpPolNo.equals(other.getGrpPolNo());
          上面的代碼有可能other.getGrpConNo方法返回一個null,順便問一下,GrpContNo字段在什么時候賦的值?  回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 12:57 ourjavasky
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 13:37 lvq810
          一樓是對的,類的屬性未賦值為Null,null值equals()就會出現NullPointerException  回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 13:39 Julia
          If you use object as key for Hashtable, you should override both
          equals() and hashCode() methods. Please see link

          http://www.ibm.com/developerworks/java/library/j-jtp05273.html
            回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 13:43 foxinsky
          @lvq810
          4樓給出的解釋應該是正確的。下面是CSDN的網友MT502給出的解答:
          MAP在執行put()的時候先調用myPolSchema的hashCode()方法看當前有沒有一樣的hashCode存在,如果沒有就直接put,有的話就調用myPolSchema的equals()方法看是否相等。
          因為你沒有實現hashCode(),所以用默認的hashCode(),所以當產生相同的hashCode的時候(在我機器上是運行到2058時),因為檢查到相同的hashcode,所以調用你自己的equals(),因為GrpContNo是null,所以這時候拋NullPointerException 。
          你機器上顯然是在1500的時候產生了相同了hashcode()。
          如果實現了hashCode(),第一次就拋NullPointerException :

          Java codepublic int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result
          + ((GrpContNo == null) ? 0 : GrpContNo.hashCode());
          result = prime * result
          + ((GrpPolNo == null) ? 0 : GrpPolNo.hashCode());
          return result;
          }


          我現在在想,如何去重寫hashCode方法才能保證生成的hashCode值不同呢……

          或者去修改我的equals算法,在調用之前先去判斷一下other.getGrpContNo==null(這兩種方法怎么實現起來才算是比較合理的算法呢?

            回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 13:57 lvq810
          只有修改equals加上判斷  回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-14 21:43 darkmagician
          如果equals是true,hashcode必須相同。 沒必要擔心不同的object有相同的hashcode, 否則還要equals干嘛, 保證hashcode分散,只是提高效率而已。  回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋[未登錄] 2009-01-15 08:40 nile black
          MAP在執行put()的時候先調用myPolSchema的hashCode()方法看當前有沒有一樣的hashCode存在,如果沒有就直接put,有的話就調用myPolSchema的equals()方法看是否相等。
          因為你沒有實現hashCode(),所以用默認的hashCode(),所以當產生相同的hashCode的時候(在我機器上是運行到2058 時),因為檢查到相同的hashcode,所以調用你自己的equals(),因為GrpContNo是null,所以這時候拋 NullPointerException 。
          你機器上顯然是在1500的時候產生了相同了hashcode()。
          如果實現了hashCode(),第一次就拋NullPointerException :   回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-19 12:37 娃娃
          樓上這個師傅解釋很正確,學習了,記得考scjp的時候,有過一個題  回復  更多評論
            
          # re: 我無法解釋的問題,請您一并來解釋 2009-01-20 14:55 笨牛
          public class myPolSchema {
          private String GrpContNo;
          private String GrpPolNo;
          public String getGrpContNo() {
          return GrpContNo;
          }
          public void setGrpContNo(String aGrpContNo) {
          GrpContNo = aGrpContNo;
          }
          public String getGrpPolNo() {
          return GrpPolNo;
          }
          public void setGrpPolNo(String aGrpPolNo) {
          GrpPolNo = aGrpPolNo;
          }
          public myPolSchema(String GrpContNo,String GrpPolNo){
          this.GrpContNo=GrpContNo;
          this.GrpPolNo=GrpPolNo;
          }
          public boolean equals(Object otherObject) {
          if (this == otherObject)
          return true;
          if (otherObject == null)
          return false;
          if (getClass() != otherObject.getClass())
          return false;
          if(!(otherObject instanceof myPolSchema)){
          return false;
          }else{
          myPolSchema other = (myPolSchema) otherObject;
          return GrpContNo.equals(other.getGrpContNo())
          && GrpPolNo.equals(other.getGrpPolNo());
          }
          }

          }

          ---------------------------

          import java.util.* ;
          public class MultiThreading{
          // implements Runnable
          Map m=Collections.synchronizedMap(new HashMap());
          //HashMap m=new HashMap();
          Hashtable t=new Hashtable();
          public myPolSchema polschema;
          public void run(int i)
          {
          polschema=new myPolSchema(i+"",i+"");
          m.put(polschema, "UPDATE");
          System.out.println("put end at " + new Date());
          }
          public static void main(String[] args) throws Exception {
          MultiThreading t=new MultiThreading();
          for(int i=0;i<=25000;i++){
          try{
          t.run(i);
          //Thread.sleep(100);
          }
          catch(Exception ex){
          //在我本地測試時當運行大概1500左右次的時間就會拋出NullPointerException
          System.out.println("i is: " + i);
          throw ex;
          }
          }
          }

          }


          構造方法啊大哥 不賦值怎么能比較呢  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 德格县| 红安县| 息烽县| 林州市| 棋牌| 霍林郭勒市| 肥城市| 根河市| 昌宁县| 伊金霍洛旗| 乌鲁木齐市| 沙坪坝区| 永仁县| 富阳市| 南乐县| 台湾省| 长汀县| 长葛市| 乡城县| 台前县| 宁河县| 平原县| 辽中县| 榆林市| 慈利县| 海城市| 兰州市| 区。| 罗城| 华安县| 富蕴县| 樟树市| 沁源县| 四平市| 娱乐| 平远县| 铅山县| 彩票| 吉安市| 延边| 邹城市|