乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      java集合中的一個(gè)移除數(shù)據(jù)陷阱(遍歷集合自身并同時(shí)刪除被遍歷數(shù)據(jù))

       為什么圖書館13 2016-06-28

      新浪微博:IT國子監(jiān)(記得關(guān)注噢) http://weibo.com/itguozijian


      下面是網(wǎng)上的其他解釋,更能從本質(zhì)上解釋原因:
      Iterator 是工作在一個(gè)獨(dú)立的線程中,并且擁有一個(gè) mutex 鎖。 Iterator 被創(chuàng)建之后會(huì)建立一個(gè)指向原來對象的單鏈索引表,當(dāng)原來的對象數(shù)量發(fā)生變化時(shí),這個(gè)索引表的內(nèi)容不會(huì)同步改變,所以當(dāng)索引指針往后移動(dòng)的時(shí)候就找不到要迭代的對象,所以按照 fail-fast 原則 Iterator 會(huì)馬上拋出 java.util.ConcurrentModificationException 異常。
      所以 Iterator 在工作的時(shí)候是不允許被迭代的對象被改變的。但你可以使用 Iterator 本身的方法 remove() 來刪除對象, Iterator.remove() 方法會(huì)在刪除當(dāng)前迭代對象的同時(shí)維護(hù)索引的一致性。


           在java常用的集合框架就是list ,set ,map 。

            list 可通過下標(biāo)進(jìn)行遍歷,set,map不能通過下表進(jìn)行遍歷,因此對于set ,map的數(shù)據(jù)遍歷時(shí),常常采用迭代器,不過在使用迭代器移除數(shù)據(jù)時(shí)存在陷阱。

            執(zhí)行如下代碼:

       

              Set set = new HashSet();

              set.add(1);

              set.add(2);

              set.add(3);

              Iterator i = set.iterator();

              while(i.hashNext()){

              Object o = i.next();

               set.remove(o);

      }

      執(zhí)行結(jié)果會(huì)出現(xiàn)以下異常:

      Exception in thread "main" java.util.ConcurrentModificationException
          at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
          at java.util.AbstractList$Itr.next(Unknown Source)

      這個(gè)問題在集合框架使用迭代器遍歷數(shù)據(jù)時(shí)存在,在java5新曾的foreach遍歷方式下也存在。在通過下表遍歷list的過程中不存在著個(gè)問題。

      如:

         List list = new ArrayList();

        list .add(1);

      list.add(2);

      list.add(3);

      for(int i = 0 ; i < list.size();i++){

         list.remove(list.get(i));|| list.remove(i);

      }

      //

      或者使用iterator的remove方法

      代碼能夠正常執(zhí)行。

       

      當(dāng)然這種情況也是容易解決,實(shí)現(xiàn)方式就是講遍歷與移除操作分離,即在遍歷的過程中,將需要移除的數(shù)據(jù)存放在另外一個(gè)集合當(dāng)中,遍歷結(jié)束之后,統(tǒng)一移除。

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

      利用java迭代器Itetator遍歷并刪除HashMap中的元素問題

      問題:
      下面的代碼試圖利用
      HashMap的Iterator對象遍歷該HashMap并刪除滿足條件的元素(比如超時(shí)的元素),但會(huì)拋出java.util.ConcurrentModificationException異常
          public static void main(String[] args)
          {      
              HashMap<String, String> hs=new HashMap();    
              hs.put("p1", "1");
              hs.put("p2", "1");
              hs.put("p3", "1");
              hs.put("p4", "1");
              hs.put("p5", "1");
              hs.put("p6", "1");       
              Iterator it=hs.keySet().iterator();      
              while(it.hasNext())
              {
                  String str=(String)it.next();               
                  System.out.println(hs);   

                   //邏輯處理.........         
                   .............
                  hs.remove(str);      
              }   
      }
          原因應(yīng)該
      hs.remove(str)后,it內(nèi)容沒變,并且it里的指針列表又重新排序,所以只要確保刪除任一元素后,it保持同步更新即可:
          解決方案一:
      刪除任一元素后,it保持同步更新
          ............
            
       Iterator it=hs.keySet().iterator();   
              while(it.hasNext())
              {
                  it=hs.keySet().iterator();  
                  String str=(String)it.next();               
                  System.out.println(hs);   

                   //邏輯處理.........         
                   .............
                  hs.remove(str);      
              }   
       
          ...........
          這樣的時(shí)間復(fù)雜度明顯太大(兩層循環(huán)嵌套)
          解決方案二:
      由于刪除元素時(shí),hs的iterator對象也重新排序,所以只要用hs的一個(gè)副本hsBack
      Uackp的iterator去遍歷hs即可,這樣在刪除hs元素時(shí)iterator就不會(huì)重排了(因?yàn)閯h除的是hs的元素,而不是該iterator所屬的
      hsBackUackp
      ...................
              hsBackUp=(HashMap<String, String>)hs.clone();
              Iterator it=hsBackUp.keySet().iterator();
              System.out.println(hsBackUp);
              while(it.hasNext())
              {
                  String str=(String)it.next();               
                  System.out.println(hs);               
                  hs.remove(str);       
              }   
      .....................
          這樣雖然時(shí)間復(fù)雜度小了(只有一層循環(huán)),可是空間復(fù)雜度大了(多了一個(gè)hashmap的拷貝);
          查閱api文檔和相關(guān)資料后,原來iterator對象有一remove方法:
      void remove() 
      Removes from the underlying collection the last element returned by the
      iterator (optional operation). This method can be called only once per
      call to 
      next
      . The behavior of an iterator is unspecified if
      the underlying collection is modified while the iteration is in
      progress in any way other than by calling this method.

      于是有下面的改進(jìn):
      解決方案三:
      ..............................
      Iterator it=hs.keySet().iterator(); 
      while(it.hasNext())
      {
      String str=(String)it.next(); 
      System.out.println(hs); 
      it.remove(); 

      ..............................

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多