Java中List的安全删除

来源:互联网 发布:边防武警转业知乎 编辑:程序博客网 时间:2024/06/08 20:18
    对于Java集合中的List来讲,删除是一个常见的操作,但是也是最容易犯错误的地方,尤其对于新手更是如此。笔者在工作中也经常看到一些工作了很长时间的老程序员在这个问题上犯错误;在这里,我将通过一个例子,给大家展示如何从List中安全的删除元素。先看下面的例子:
    假如我有一个List,其中包含了6个元素,我想删除其中的前面4个,应该如何做;好多程序员不加思索,写下了下面的代码:
    
 1private void unSafeDeleteTopByCount(List list) {
 2        try {
 3            for (int i = 0; i < 4; i++{
 4                list.remove(i);
 5            }

 6        }
 catch (Exception e) {
 7            e.printStackTrace();
 8        }
 
    大家可以新建一个List,然后新建一个类在main中调用一下这个方法,看看结果会如何:看到了吧,程序抛出了异常,如下:
    java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
 at java.util.ArrayList.RangeCheck(Unknown Source)
 at java.util.ArrayList.remove(Unknown Source)
 at com.lpx.collection.TestArrayDeletion.unSafeDeleteTopByCount(TestArrayDeletion.java:59)
 at com.lpx.collection.TestArrayDeletion.main(TestArrayDeletion.java:26)
    看到这里,可能大家已经明白了;对了,在删除的过程中,List的size发生了变化,但是index没有变化,就会造成index>=size的情况发生,抛出IndexOutOfBoundsException是一定的。这还算好的,至少你知道有异常,但是还有一种更隐蔽的情况,如果你删除的个数是3个,IndexOutOfBoundsException是不会发生的,但是删除后的List不是你想要的结果。具体是
private void unSafeDeleteTopByCount(int count) {
        
try {
            
for (int i = 0; i < count; i++{
                list.remove(i);
            }

        }
 catch (Exception e) {
            e.printStackTrace();
        }
 finally {
            print();
        }

    }


private void print() {
        
for (String str : list) {
            System.out.println(str);
        }

    }


List
<String> list = new ArrayList<String>();
for(int i=0;i<6;i++){
       list.add(
"str"+i);
}

unSafeDeleteTopByCount(
3);
   什么意思呢,大家可以看一下上面的代码,如果运行的话,打印出的结果是:
    str1
    str3
    str5
   为什么呢,当我们删除了index为0的元素【str0】后,由于List的size变化,index为0的元素会变为str1,而index为1的元素会变为str2,这时由
private void safeDeletionTopByCountMethod1(int count) {
        System.out.println(
"*********safeDeletionTopByCountMethod1*********");
        
for (int i = count - 1; i >= 0; i--{
            list.remove(i);
        }

        print();
    }


    
private void safeDeletionTopByCountMethod2(int count) {
        System.out.println(
"*********safeDeletionTopByCountMethod2*********");
        
for (int i = 0; i < count; i++{
            list.remove(
0);
        }

        print();
    }


    
private void safeDeletionTopByCountMethod3(int count) {
        System.out.println(
"*********safeDeletionTopByCountMethod3*********");
        List
<String> localList = new ArrayList<String>();
        
for (int i = 0; i < count; i++{
            localList.add(list.get(i));
        }

        list.removeAll(localList);
        print();
    }


    
private void safeDeletionTopByCountMethod4(int count) {
        System.out.println(
"*********safeDeletionTopByCountMethod4*********");
        List
<String> localList = new ArrayList<String>();
        localList.addAll(list);
        
for (int i = 0; i < count; i++{
            String str 
= localList.get(i);
            list.remove(str);
        }

        print();
    }
于index为1,所以str2会被删除;你可以自己去推算一下结果。
如何解决这个问题呢,笔者在上面给出了4种方法供大家参考,最后给出了完整的代码。
*****************************************************************************

package com.lpx.collection;

import java.util.ArrayList;
import java.util.List;

public class TestArrayDeletion {

 private List<String> list = null;
 public static String[] array = { "str0", "str1", "str2", "str3", "str4",
   "str5" };

 public TestArrayDeletion() {
  super();
  list = new ArrayList<String>();
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  TestArrayDeletion arrayDeletion = new TestArrayDeletion();
  arrayDeletion.initList();
  arrayDeletion.unSafeDeleteTopByCount(3);

  arrayDeletion.initList();
  arrayDeletion.unSafeDeleteTopByCount(4);

  arrayDeletion.initList();
  arrayDeletion.safeDeletionTopByCountMethod1(4);

  arrayDeletion.initList();
  arrayDeletion.safeDeletionTopByCountMethod2(4);

  arrayDeletion.initList();
  arrayDeletion.safeDeletionTopByCountMethod3(4);

  arrayDeletion.initList();
  arrayDeletion.safeDeletionTopByCountMethod4(4);

 }

 private void initList() {
  list.clear();
  for (String str : array) {
   list.add(str);
  }
 }

 private void print() {
  for (String str : list) {
   System.out.println(str);
  }
 }

 private void unSafeDeleteTopByCount(int count) {
  System.out.println("*********unSafeDeleteTopByCount*********");
  try {
   for (int i = 0; i < count; i++) {
    list.remove(i);
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   print();
  }
 }

 private void safeDeletionTopByCountMethod1(int count) {
  System.out.println("*********safeDeletionTopByCountMethod1*********");
  for (int i = count - 1; i >= 0; i--) {
   list.remove(i);
  }
  print();
 }

 private void safeDeletionTopByCountMethod2(int count) {
  System.out.println("*********safeDeletionTopByCountMethod2*********");
  for (int i = 0; i < count; i++) {
   list.remove(0);
  }
  print();
 }

 private void safeDeletionTopByCountMethod3(int count) {
  System.out.println("*********safeDeletionTopByCountMethod3*********");
  List<String> localList = new ArrayList<String>();
  for (int i = 0; i < count; i++) {
   localList.add(list.get(i));
  }
  list.removeAll(localList);
  print();
 }

 private void safeDeletionTopByCountMethod4(int count) {
  System.out.println("*********safeDeletionTopByCountMethod4*********");
  List<String> localList = new ArrayList<String>();
  localList.addAll(list);
  for (int i = 0; i < count; i++) {
   String str = localList.get(i);
   list.remove(str);
  }
  print();
 }
}


0 0