1. 简介java
有时候须要在集合遍历过程当中进行增/删,下面介绍几种正确的操做方式。spa
2. 示例code
例若有以下集合[1, 2, 2, 3, 5],须要删除被2整除的元素。blog
1 import java.util.*; 2 3 public class ListFunc2 { 4 5 public static void main(String[] args){ 6 String str = "12235"; 7 String[] arr = str.split(""); 8 List<String> list1 = new ArrayList<>(Arrays.asList(arr)); 9 List<String> list2 = new ArrayList<>(Arrays.asList(arr)); 10 List<String> list3 = new ArrayList<>(Arrays.asList(arr)); 11 List<String> list4 = new ArrayList<>(Arrays.asList(arr)); 12 List<String> list5 = new ArrayList<>(Arrays.asList(arr)); 13 List<String> list6 = new ArrayList<>(Arrays.asList(arr)); 14 15 System.out.println(list1); // [1,2,2,3,5]
2.1 正序方式索引
从集合的第一个元素开始遍历:rem
1 // 正序方式 2 for(int i=0; i<list2.size(); i++){ 3 int value = Integer.parseInt(list2.get(i)); 4 if(value%2==0){ 5 list2.remove(i); 6 } 7 } 8 System.out.println(list2); // [1, 2, 3 ,5]
发现未彻底删除能够被2整除的元素,缘由以下:当i=1时删除第二个元素2,此时后面的元素会前移;然而下次遍历时索引i=2,get
对应的元素为3,跳过了原集合中的第三个元素2。it
0 1 2 3 4 // index 1 2 2 3 5 1 2 3 5
此时尝试对索引进行修正,将索引从新指向原集合的第三个元素:class
1 for(int i=0; i<list3.size(); i++){ 2 int value = Integer.parseInt(list3.get(i)); 3 if(value%2==0){ 4 list3.remove(i); 5 i--; // 修正 6 } 7 } 8 System.out.println(list3); // [1, 3, 5]
2.2 逆序方式import
从集合的最后一个元素开始向前遍历:
1 // 逆序方式 2 for(int i= list4.size()-1; i>=0; i--){ 3 int value = Integer.parseInt(list4.get(i)); 4 if(value%2==0){ 5 list4.remove(i); 6 } 7 } 8 System.out.println(list4); // [1, 3, 5]
索引和集合的对应变化过程以下:
当索引为2时,删除集合中的第三个元素2,此时集合中的后续元素前移;而后索引变为1,删除集合中的第二个元素2;
能够发现,后续元素的前移不会致使索引的跳跃,不影响前面的元素。
0 1 2 3 4 // index 1 2 2 3 5 1 2 3 5
2.3 Iterator方式
推荐使用Iterator对遍历过程当中的集合进行修改,不用担忧索引的跳跃和越界状况。
1 // iterator迭代器 2 for(Iterator<String> it = list5.iterator(); it.hasNext();){ 3 int value = Integer.parseInt(it.next()); 4 if(value%2==0){ 5 it.remove(); 6 } 7 } 8 System.out.println(list5); // [1, 3, 5] 9 10 Iterator<String> it = list6.iterator(); 11 while(it.hasNext()){ 12 int value = Integer.parseInt(it.next()); 13 if(value%2==0){ 14 it.remove(); 15 } 16 } 17 System.out.println(list6); // [1, 3, 5]
2.4 Java 8 新特性
直接使用boolean removeIf(Predicate<? super E> filter)方法
1 // java 8最新方法 2 list1.removeIf(v->Integer.parseInt(v)%2==0); // v表示集合中的元素,给出适当条件过滤 3 System.out.println(list1); // [1, 3, 5]
!!!