您的位置:首页 > 编程语言 > Java开发

Java List Copy,Remove容易出现的问题

2015-08-07 10:57 357 查看
Java List Copy,Remove容易出现的问题

主题:List删除元素,复制元素

平台:Window + Eclipse3.3 + JDK6

懒程序员,在代码越写越多的情况下,总想着使用把代码精简一下,能不写if else的,能不写for循环的尽量不想写,但是遇到的问题都要解决的呀,因此调用同逻辑的已存在方法便是首选。


  今天就集合类(List)两个容易出错的方法做个记录,可以引以为戒,并且也提供正常的使用方式, 都是在java.utils包,方便使用。

  package com.longer.list;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

import junit.framework.TestCase;

/**

*

* @author Longer

* Apr 23, 2010 2:49:13 PM

*/

public class ListTest extends TestCase {

class TempBean{

public TempBean( String str ){
this.str = str;
}

String str;

public String getStr() {
return str;
}

public void setStr(String str) {
this.str = str;
}
}

List<TempBean> tempList = null;
protected void setUp() throws Exception {
super.setUp();

tempList = new ArrayList<TempBean>();
tempList.add( new TempBean("1") );
tempList.add( new TempBean("2") );
tempList.add( new TempBean("30") );
tempList.add( new TempBean("31") );
tempList.add( new TempBean("3") );
}

protected void tearDown() throws Exception {
super.tearDown();

tempList.clear();
tempList = null;
}

public void testRemove1(){

for (TempBean bean : tempList ) {
//exception:java.util.ConcurrentModificationException
//tempList.remove( bean );
}
System.out.println( tempList );
}

public void testRemove2(){

for (int i = 0; i < tempList.size(); i++) {
TempBean bean = tempList.get(i);
tempList.remove( i );//or tempList.remove(bean);
i--;
}
System.out.println( tempList );
}

public void testRemove3(){

System.out.println("before remove:" + tempList );
for (Iterator iterator = this.tempList.iterator(); iterator.hasNext();) {
iterator.remove();
//exception:java.lang.IllegalStateException
//tempList.add( new TempBean("") );
}
System.out.println("after remove:"+ tempList );
}

public void testCopy1(){

List<TempBean> newList = new ArrayList<TempBean>();
//exception:java.lang.IndexOutOfBoundsException: Source does not fit in dest
//Collections.copy( newList, tempList );
}

public void testCopy2(){

List<TempBean> newList = new ArrayList<TempBean>(Arrays.asList(new TempBean[ this.tempList.size()]));
Collections.copy( newList, tempList );
System.out.println( newList );
}


}

  异常解释:

  1:testRemove1–>java.util.ConcurrentModificationException

  此类的JavaDOC部分原文:

    This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible。

  简单翻译:

      检测到一个对象存在同步修改,并且此修改不被允许的情况下,此异常将被方法抛出。

  因此, 可以看出List是不支持同步修改的,其实整个Collection、Map都与List一样的情况,详细的原因得从迭代器Iterator去研究,这里不做分析。大概理解是Iterator在遍历的时间内,其源对象索引发生了改变,导致了不同步现象。

  2)testRemove3–>java.lang.IllegalStateException

  此类的JavaDOC部分原文:

    Signals that a method has been invoked at an illegal or inappropriate time

  简单翻译:

    信息灯,一个方法在非法或者不恰当的时间内被调用。

  因此,问题的根源同上。

  3)testCopy1–>java.lang.IndexOutOfBoundsException

  Collections.copy JavaDOC部分原文:

    ……The destination list must be at least as long as the source list…….

  简单翻译:

    目的list必须至少要与源list等长。(目的List可以比源List长度长)

  因此, 它这里指的长度是List里的size()方法值,我们都知道new ArrayList()初始化的时候size()等于0,即便是你使用new ArrayList(10)来初始化,也只是预设了一个initialCapacity==10的存储空间,size()还是等于0。因此在使用Collections.copy之前,需要把目的List加一些空的元素,直到目的List的size()值与源List的size()值等长(或更长)。

list 动态数组在删除元素后后面的元素索引会加-1 替代删除元素 所以当我们在删除了list中元素后还需遍历查找为了不遗漏list中的元素需要将循环变量同时-1 如下代码:

for(int i=0;i<findTeachers.size();i++){
Teacher teacher=findTeachers.get(i);
teacher.setSubscribeSum(this.getValueForInt("famous:subNum:"+1241));
//teacher.setStartStudySum(this.getValueForInt("famous:videoNum:"+teacher.getMid()));
teacher.setVideoSum(this.getValueForInt("famous:videoNum:"+1241));
if(teacher.getCityName().equals(city)){
currentCityTeacher.add(teacher);
findTeachers.remove(teacher);
--i;// 保证遍历每个元素
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: