最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HashMap和List遍歷方法及如何遍歷刪除元素總結

 更新時間:2019年05月31日 10:14:03   投稿:laozhang  
在本篇文章中小編給大家分享了關于HashMap和List遍歷方法及如何遍歷刪除元素知識點總結,需要的朋友們參考下。

相信大家對集合遍歷再熟悉不過了,這里總結一下HashMap和List的遍歷方法,以及它們該如何實現(xiàn)遍歷刪除。

這里對于每種遍歷刪除出現(xiàn)的問題的原因都給出了詳解!

(一)List的遍歷方法及如何實現(xiàn)遍歷刪除

我們造一個list出來,接下來用不同方法遍歷刪除,如下代碼:

List<String> list= new ArrayList<String>();
  famous.add("zs");
  famous.add("ls");
  famous.add("ww");
  famous.add("dz");

1、for循環(huán)遍歷list:

 for(int i=0;i<list.size();i++){
       if(list.get(i).equals("ls"))
       list.remove(i);
      }

這是一種很常見的遍歷方式,但是使用這種遍歷刪除元素會出現(xiàn)問題,原因在于刪除某個元素后,list的大小發(fā)生了變化,而你的索引也在變化,所以會導致你在遍歷的時候漏掉某些元素。比如當你刪除第一個元素后,繼續(xù)根據(jù)索引訪問第二個元素后,因為刪除的原因,后面的元素都往前移動了以為,所以實際訪問的是第三個元素。因此,這種遍歷方式可以用在讀取元素,而不適合刪除元素。

2、增強for循環(huán):

    for(String x:list){
      if(x.equals("ls"))
      list.remove(x);
    }

這也是一種很常見的遍歷方式,但是使用這種遍歷刪除元素也會出現(xiàn)問題,運行時會報ConcurrentModificationException異常
其實增強for循環(huán)是java語法糖的一種體現(xiàn),如果大家通過反編譯得到字節(jié)碼,那么上面這段代碼的內部實現(xiàn)如下所示:

for(Iterator<String> it = list.iterator();it.hasNext();){
     String s = it.next();
     if(s.equals("madehua")){
       list.remove(s);
     }
   }

下面就解釋為什么會報ConcurrentModificationException異常。分析Iterator的源代碼,重點分析整個調用該過程中的
函數(shù)(hasNext和remove):

private class Itr implements Iterator<E> {
	    int cursor;    // index of next element to return
	    int lastRet = -1; // index of last element returned; -1 if no such
	    int expectedModCount = modCount;
 
 
	    public boolean hasNext() {
	      return cursor != size; // size為集合中元素的個數(shù)
	    }
 
 
	    public E next() {
	      checkForComodification();
	      int i = cursor;
	      if (i >= size)
	        throw new NoSuchElementException();
	      Object[] elementData = ArrayList.this.elementData;
	      if (i >= elementData.length)
	        throw new ConcurrentModificationException();
	      cursor = i + 1;
	      return (E) elementData[lastRet = i];
	    }
 
 
	    /* 此方法并沒被調用,只是調用List.remove方法
	    public void remove() {
	      checkForComodification();
	      try {
	        ArrayList.this.remove(lastRet);	// size字段減1
	        cursor = lastRet;
	        lastRet = -1;
	        expectedModCount = modCount;
	      } catch (IndexOutOfBoundsException ex) {
	        throw new ConcurrentModificationException();
	      }
	    }
	    */
 
 
	    final void checkForComodification() {	// 檢查修改和當前版本號是否一致,不一致則拋出異常
	      if (modCount != expectedModCount)
	        throw new ConcurrentModificationException();
	    }
 
 
  	}
 
 
  	// List.remove
  	@Override public boolean remove(Object object) {
	    Object[] a = array;
	    int s = size;
	    if (object != null) {
	      for (int i = 0; i < s; i++) {
	        if (object.equals(a[i])) {
	          System.arraycopy(a, i + 1, a, i, --s - i);
	          a[s] = null; // Prevent memory leak
	          size = s;
	          modCount++;	// 核心代碼:修改了版本號。這樣當checkForComodification的時候,modCount值就和expectedModCount不同
	          return true;
	        }
	      }
	    } else {
	      for (int i = 0; i < s; i++) {
	        if (a[i] == null) {
	          System.arraycopy(a, i + 1, a, i, --s - i);
	          a[s] = null; // Prevent memory leak
	          size = s;
	          modCount++;
	          return true;
	        }
	      }
	    }
	    return false;
	  }

接下來梳理一下流程,這時候你就會發(fā)現(xiàn)這個異常是在next方法的checkForComodification中拋出的。拋出的原因是
modCount !=expectedModCount。這里的modCount是指這個list對象從呢我出來到現(xiàn)在被修改的次數(shù),當調用list
的add或者remove方法的時候,這個modCount都會自動增減;iterator創(chuàng)建的時候modCount被復制給了
expectedModcount,但是調用list的add和remove方法的時候不會同時自動增減expectedModcount,這樣就導致
兩個count不相等,從而拋出異常。大家如果理解了上面的執(zhí)行流程,以后碰到類似這種問題,比如如果刪除的是倒數(shù)
第二個元素卻不會碰到異常。就會知道為什么了。

3、iterator遍歷刪除

   Iterator<String> it = list.iterator();
   while(it.hasNext()){
    String x = it.next();
    if(x.equals("del")){
      it.remove();
   }
  }

這種方式是可以正常遍歷和刪除的。但是你可能看到上面代碼感覺和增強for循環(huán)內部實現(xiàn)的代碼差不多,其實差別就在于上面使用一個使用list.remove(),一個使用it.remove()。

(二)HashMap的遍歷刪除及如何實現(xiàn)遍歷刪除

一樣我們先造一個hashmap出來,如下

	private static HashMap<Integer, String> map = new HashMap<Integer, String>();;
 
	public static void main(String[] args) {
		
		 for(int i = 0; i < 10; i++){ 
	      map.put(i, "value" + i); 
	    } 
	 
	
	}

1、第一種遍歷刪除:

    for(Map.Entry<Integer, String> entry : map.entrySet()){ 
       Integer key = entry.getKey(); 
       if(key % 2 == 0){ 
         System.out.println("To delete key " + key); 
         map.remove(key); 
         System.out.println("The key " + + key + " was deleted"); 
       } 

這種遍歷刪除依舊會報ConcurrentModificationException異常,

2、第二種遍歷刪除:

    Set<Integer> keySet = map.keySet();
	   for(Integer key : keySet){
	      if(key % 2 == 0){
	        System.out.println("To delete key " + key);
	        keySet.remove(key);
	        System.out.println("The key " + + key + " was deleted");
	      }
	   }

這種遍歷刪除依舊會報ConcurrentModificationException異常,

3、第三種遍歷刪除:

  Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
    while(it.hasNext()){
      Map.Entry<Integer, String> entry = it.next();
      Integer key = entry.getKey();
      if(key % 2 == 0){
      	 System.out.println("To delete key " + key);
      	 it.remove();  
      	 System.out.println("The key " + + key + " was deleted");
 
      }
    }

這種遍歷是OK的

分析上述原因,如果大家理解了List的遍歷刪除,那么感覺HashMap的遍歷刪除是不是有類似之處啊。下面就分析一下原因:
如果查詢源代碼以上的三種的刪除方式都是通過調用HashMap.removeEntryForKey方法來實現(xiàn)刪除key的操作。
在removeEntryForKey方法內知識一場了key  modCount就會執(zhí)行一次自增操作,此時modCount就與expectedModCOunt不一致了
,上面三種remove實現(xiàn)中,只有第三種iterator的remove方法在調用完removeEntryForKey方法后同步了expectedModCount值與
modCount相同,所以iterator方式不會拋出異常。最后希望大家遇到問題到查詢源代碼,它會給你最好的解釋!
---------------------
作者:demohui
來源:CSDN
原文:https://blog.csdn.net/demohui/article/details/77748809
版權聲明:本文為博主原創(chuàng)文章,轉載請附上博文鏈接!

相關文章

  • java實現(xiàn)飛機大戰(zhàn)游戲

    java實現(xiàn)飛機大戰(zhàn)游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)飛機大戰(zhàn)游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • java實用驗證碼的實現(xiàn)代碼

    java實用驗證碼的實現(xiàn)代碼

    這篇文章主要為大家介紹了java實用驗證碼的實現(xiàn)代碼,驗證碼實際上就是隨機選擇一些字符以圖片的形式展現(xiàn)在頁面上,感興趣的小伙伴們可以參考一下
    2016-03-03
  • 詳解Spring Boot中整合Sharding-JDBC讀寫分離示例

    詳解Spring Boot中整合Sharding-JDBC讀寫分離示例

    這篇文章主要介紹了詳解Spring Boot中整合Sharding-JDBC讀寫分離示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • 基于Spring@Autowired注解與自動裝配詳談

    基于Spring@Autowired注解與自動裝配詳談

    下面小編就為大家?guī)硪黄赟pring@Autowired注解與自動裝配詳談。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java多線Condition條件變量正確使用方法詳解

    Java多線Condition條件變量正確使用方法詳解

    這篇文章主要為大家,介紹了Java多線Condition條件變量正確使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 記一次springboot中用undertow的坑

    記一次springboot中用undertow的坑

    這篇文章主要介紹了記一次springboot中用undertow的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java多線程學習筆記

    Java多線程學習筆記

    常用的實現(xiàn)多線程的兩種方式:Thread和Runnable。之所以說是“常用”,是因為在Java 5后可以通過java.util.concurrent包中的線程池來實現(xiàn)多線程
    2021-09-09
  • Java獲取mac地址的方法

    Java獲取mac地址的方法

    這篇文章主要介紹了Java獲取mac地址的方法,涉及java針對系統(tǒng)硬件及IO操作的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • Springboot如何使用filter對request body參數(shù)進行校驗

    Springboot如何使用filter對request body參數(shù)進行校驗

    這篇文章主要介紹了Springboot如何使用filter對request body參數(shù)進行校驗,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot中@RestController注解實現(xiàn)

    springboot中@RestController注解實現(xiàn)

    在JavaWeb開發(fā)中,Spring框架及其組件SpringMVC因高效和強大功能而廣受歡迎,@RestController注解是SpringMVC中的重要組成部分,下面就來介紹一下,感興趣的可以了解一下
    2024-09-09

最新評論

邵阳县| 孟村| 绵阳市| 开化县| 凤冈县| 鹤庆县| 新津县| 叙永县| 沙洋县| 徐闻县| 嘉鱼县| 光泽县| 黑山县| 托克逊县| 洛川县| 梁平县| 青岛市| 金湖县| 延庆县| 亚东县| 嘉祥县| 锡林郭勒盟| 邹城市| 龙江县| 简阳市| 富阳市| 谢通门县| 蒙阴县| 邢台县| 成武县| 齐河县| 米林县| 瓦房店市| 四会市| 佛学| 韶关市| 栾城县| 滁州市| 稻城县| 北川| 柳江县|