一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - Java如何在List或Map遍歷過程中刪除元素

Java如何在List或Map遍歷過程中刪除元素

2020-07-09 11:22daisy JAVA教程

相信大家在日常的開發過程中,經常需要對List或Map里面的符合某種業務的數據進行刪除,但是如果不了解里面的機制就容易掉入“陷阱”導致遺漏或者程序異常。下面這篇文章將會給大家詳細介紹Java如何在List和Map遍歷過程中刪除

遍歷刪除ListMap中的元素有很多種方法,當運用不當的時候就會產生問題。下面通過這篇文章來再學習學習吧。

一、List遍歷過程中刪除元素

使用索引下標遍歷的方式

示例:刪除列表中的2

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
  
  for (int i = 0; i < list.size(); i++) {
   if(2 == list.get(i)){
    list.remove(i);
   }
   System.out.println(list.get(i));
  }
  
  System.out.println("list=" + list.toString());
  
 }

輸出結果:

?
1
2
3
4
5
1
2
3
4
list=[1, 2, 3, 4]

問題:

結果顯示只刪除了一個2,另一個2被遺漏了,原因是:刪除了第一個2后,集合里的元素個數減1,后面的元素往前移了1位,導致了第二個2被遺漏了。

使用For循環遍歷的方式

示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void listIterator2(){
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
  
  for (int value : list) {
   if(2 == value){
    list.remove(value);
   }
   System.out.println(value);
  }
  
  System.out.println("list=" + list.toString());
  
 }

結果:

?
1
2
3
4
5
6
7
Exception in thread "main" 1
2
java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
 at java.util.ArrayList$Itr.next(Unknown Source)
 at test.ListIterator.listIterator2(ListIterator.java:39)
 at test.ListIterator.main(ListIterator.java:10)

說明:

jdk中對ConcurrentModificationException的描述:

public class ConcurrentModificationException extends

RuntimeException當方法檢測到對象的并發修改,但不允許這種修改時,拋出此異常。

例如,某個線程在 Collection 上進行迭代時,通常不允許另一個線性修改該 Collection。通常在這些情況下,迭代的結果是不確定的。如果檢測到這種行為,一些迭代器實現(包括 JRE 提供的所有通用 collection 實現)可能選擇拋出此異常。執行該操作的迭代器稱為快速失敗 迭代器,因為迭代器很快就完全失敗,而不會冒著在將來某個時間任意發生不確定行為的風險。

注意:此異常不會始終指出對象已經由不同 線程并發修改。如果單線程發出違反對象協定的方法調用序列,則該對象可能拋出此異常。例如,如果線程使用快速失敗迭代器在 collection 上迭代時直接修改該 collection,則迭代器將拋出此異常。

注意:迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步并發修改做出任何硬性保證。快速失敗操作會盡最大努力拋出 ConcurrentModificationException。因此,為提高此類操作的正確性而編寫一個依賴于此異常的程序是錯誤的做法,正確做法是:ConcurrentModificationException 應該僅用于檢測 bug。

Java中的For each實際上使用的是iterator進行處理的。而iterator是不允許集合在iterator使用期間刪除的。所以導致了iterator拋出了ConcurrentModificationException

正確的方式

示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void listIterator3(){
  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(2);
  list.add(3);
  list.add(4);
  
  Iterator<Integer> it = list.iterator();
  while (it.hasNext()){
   Integer value = it.next();
   if (2 == value) {
    it.remove();
   }
   
   System.out.println(value);
  }
  
  System.out.println("list=" + list.toString());
 }

結果:

?
1
2
3
4
5
6
1
2
2
3
4
list=[1, 3, 4]

二、Map遍歷過程中刪除元素

正確做法的示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static void main(String[] args) {
 HashMap<String, String> map = new HashMap<String, String>();
 map.put("1", "test1");
 map.put("2", "test2");
 map.put("3", "test3");
 map.put("4", "test4");
 
 //完整遍歷Map
 for (Entry<String, String> entry : map.entrySet()) {
  System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue());
 }
 
 //刪除元素
 Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
 while(it.hasNext())
 {
  Map.Entry<String, String> entry= it.next();
  String key= entry.getKey();
  int k = Integer.parseInt(key);
  if(k%2==1)
  {
   System.out.printf("delete key:%s value:%s\r\n", key, entry.getValue());
   it.remove();
  }
 }
 
 //完整遍歷Map
 for (Entry<String, String> entry : map.entrySet()) {
  System.out.printf("key: %s value:%s\r\n", entry.getKey(), entry.getValue());
 }
}

結果:

?
1
2
3
4
5
6
7
8
key: 1 value:test1
key: 2 value:test2
key: 3 value:test3
key: 4 value:test4
delete key:1 value:test1
delete key:3 value:test3
key: 2 value:test2
key: 4 value:test4

注意

但對于iterator的remove()方法,也有需要我們注意的地方:

每調用一次iterator.next()方法,只能調用一次remove()方法。

調用remove()方法前,必須調用過一次next()方法。

JDK-API中對于remove()方法的描述:

void remove()從迭代器指向的集合中移除迭代器返回的最后一個元素(可選操作)。每次調用 next 只能調用一次此方法。如果進行迭代時用調用此方法之外的其他方式修改了該迭代器所指向的集合,則迭代器的行為是不明確的。

拋出:UnsupportedOperationException - 如果迭代器不支持 remove 操作。IllegalStateException - 如果尚未調用 next 方法,或者在上一次調用 next 方法之后已經調用了remove 方法。

總結

以上就是關于List與Map的遍歷過程中刪除元素的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一卡二卡3卡4卡四卡在线 | 99国产国人青青视频在线观看 | 国产在线看片护士免费视频 | 成人午夜毛片 | 成人国产在线播放 | 日日爱669| 黑人同学征服教师麻麻 | 欧美影院一区二区 | 韩日视频在线观看 | 天天操天天爽天天射 | 花房乱爱在线观看 | uoco福利姬| 午夜尤物 | 美女舒服好紧太爽了视频 | 色狼屋 | 国产精品午夜国产小视频 | 911爱豆传媒国产 | 色在线亚洲视频www 色欲麻豆国产福利精品 | 香蕉久久久久 | 91国内精品线免费播放 | 男人日女人的b | 91视频www | 风间由美一区二区播放合集 | 日韩在线免费播放 | 欧美美女被艹 | 国产乱子伦在线观看不卡 | 私人家庭影院5577 | 亚洲欧美日本在线观看 | 翁公与小莹在客厅激情 | 成人国产第一区在线观看 | 亚洲欧美日韩在线观看看另类 | 久久亚洲免费视频 | 日本片免费观看一区二区 | 人妖欧美一区二区三区四区 | 国产成人精品一区 | 国产成人亚洲综合网站不卡 | 日韩欧美中文字幕一区 | 高h肉厨房 | 欧美日韩亚洲区久久综合 | 国产精品怡红院在线观看 | 三星w699 |