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

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          情景上這樣的:我有一個(gè)重寫(xiě)了equals方法的類,該類源碼如下。然后用一程序?qū)⒋祟惗啻窝h(huán)put到HashMap中去,但每次put到1500次左右時(shí),就會(huì)出現(xiàn)NullPointerException。
            在map.put的方法中,會(huì)先去判斷put進(jìn)去的對(duì)象是否已經(jīng)存在于map中,判斷方法調(diào)用的就是該對(duì)象的重寫(xiě)的equals方法,如果說(shuō)我寫(xiě)的equals有問(wèn)題的話,為什么前1000多次左右不會(huì)出現(xiàn)問(wèn)題而在最后出現(xiàn)問(wèn)題呢?起初以為是放到HashMap中的對(duì)象太大會(huì)出現(xiàn)內(nèi)存溢出,但并未出現(xiàn)outofmemory異常,用JProfiler進(jìn)行監(jiān)測(cè)時(shí)也發(fā)現(xiàn)和heap的使用也沒(méi)關(guān)系……有哪位兄弟幫我解釋一下……

            重寫(xiě)了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());
              }

          }

          測(cè)試類:

          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){
                          
          //在我本地測(cè)試時(shí)當(dāng)運(yùn)行大概1500左右次的時(shí)間就會(huì)拋出NullPointerException
                          System.out.println("i is: " + i);
                          
          throw ex;
                      }

                  }

              }


          }

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

          FeedBack:
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 12:54 銀河使者
          只1500次,不可能產(chǎn)生內(nèi)存溢出異常,根據(jù)你的描述是拋出NullPointerException異常,這說(shuō)明你引用了一個(gè)對(duì)象變量,但這個(gè)對(duì)象變量值為null,問(wèn)題出在equals方法中,有可能出在下面的代碼中:

          myPolSchema other = (myPolSchema) otherObject;
          return GrpContNo.equals(other.getGrpContNo())
          && GrpPolNo.equals(other.getGrpPolNo());
          上面的代碼有可能other.getGrpConNo方法返回一個(gè)null,順便問(wèn)一下,GrpContNo字段在什么時(shí)候賦的值?  回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 12:57 ourjavasky
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 13:37 lvq810
          一樓是對(duì)的,類的屬性未賦值為Null,null值equals()就會(huì)出現(xiàn)NullPointerException  回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 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
            回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 13:43 foxinsky
          @lvq810
          4樓給出的解釋?xiě)?yīng)該是正確的。下面是CSDN的網(wǎng)友MT502給出的解答:
          MAP在執(zhí)行put()的時(shí)候先調(diào)用myPolSchema的hashCode()方法看當(dāng)前有沒(méi)有一樣的hashCode存在,如果沒(méi)有就直接put,有的話就調(diào)用myPolSchema的equals()方法看是否相等。
          因?yàn)槟銢](méi)有實(shí)現(xiàn)hashCode(),所以用默認(rèn)的hashCode(),所以當(dāng)產(chǎn)生相同的hashCode的時(shí)候(在我機(jī)器上是運(yùn)行到2058時(shí)),因?yàn)闄z查到相同的hashcode,所以調(diào)用你自己的equals(),因?yàn)镚rpContNo是null,所以這時(shí)候拋NullPointerException 。
          你機(jī)器上顯然是在1500的時(shí)候產(chǎn)生了相同了hashcode()。
          如果實(shí)現(xiàn)了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;
          }


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

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

            回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 13:57 lvq810
          只有修改equals加上判斷  回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-14 21:43 darkmagician
          如果equals是true,hashcode必須相同。 沒(méi)必要擔(dān)心不同的object有相同的hashcode, 否則還要equals干嘛, 保證hashcode分散,只是提高效率而已。  回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋[未登錄](méi) 2009-01-15 08:40 nile black
          MAP在執(zhí)行put()的時(shí)候先調(diào)用myPolSchema的hashCode()方法看當(dāng)前有沒(méi)有一樣的hashCode存在,如果沒(méi)有就直接put,有的話就調(diào)用myPolSchema的equals()方法看是否相等。
          因?yàn)槟銢](méi)有實(shí)現(xiàn)hashCode(),所以用默認(rèn)的hashCode(),所以當(dāng)產(chǎn)生相同的hashCode的時(shí)候(在我機(jī)器上是運(yùn)行到2058 時(shí)),因?yàn)闄z查到相同的hashcode,所以調(diào)用你自己的equals(),因?yàn)镚rpContNo是null,所以這時(shí)候拋 NullPointerException 。
          你機(jī)器上顯然是在1500的時(shí)候產(chǎn)生了相同了hashcode()。
          如果實(shí)現(xiàn)了hashCode(),第一次就拋NullPointerException :   回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 2009-01-19 12:37 娃娃
          樓上這個(gè)師傅解釋很正確,學(xué)習(xí)了,記得考scjp的時(shí)候,有過(guò)一個(gè)題  回復(fù)  更多評(píng)論
            
          # re: 我無(wú)法解釋的問(wèn)題,請(qǐng)您一并來(lái)解釋 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){
          //在我本地測(cè)試時(shí)當(dāng)運(yùn)行大概1500左右次的時(shí)間就會(huì)拋出NullPointerException
          System.out.println("i is: " + i);
          throw ex;
          }
          }
          }

          }


          構(gòu)造方法啊大哥 不賦值怎么能比較呢  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 麟游县| 始兴县| 阳信县| 建湖县| 光山县| 都兰县| 安龙县| 大化| 定日县| 五原县| 潞西市| 夹江县| 湛江市| 乐山市| 临澧县| 泸定县| 曲阜市| 福安市| 庆城县| 乳山市| 加查县| 龙江县| 嘉鱼县| 改则县| 西乌珠穆沁旗| 绥化市| 大田县| 宜阳县| 大埔县| 安阳市| 平原县| 米泉市| 普格县| 阳谷县| 淮安市| 察哈| 弥渡县| 田阳县| 汤阴县| 故城县| 毕节市|