package com.study.java.connections; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * * @author Administrator * List 接口方法测试 */ public class ListTest { /** * 集合List接口基本用法 * @param a * @param c */ public static void basicTest(List<String> a,Collection c){ a.add("A"); //指定位置添加元素 a.add(1, "B"); List<String> list1 = new ArrayList<String>(c); //指定位置添加集合 a.addAll(2, list1); //打印指定位置元素,通过索引取得元素 System.out.println(a.get(1)); //集合是否包含该元素 System.out.println("是否包含元素 "+a.contains("A")); //返回元素第一次出现位置索引 System.out.println("第一次出现位置索引 "+a.indexOf("B")); //返回元素最后一次出现位置索引 System.out.println("最后一次出现位置索引 "+a.lastIndexOf("B")); //将指定位置元素替换 a.set(2, "C"); System.out.println("集合大小 "+a.size()); //截取指定位置集合 List<String> list2 = a.subList(0, 2); System.out.println("截取集合 "+list2); //返回集合大小 System.out.println("集合大小 "+a.size()); //集合转换数组 System.out.println("转换数组 "+a.toArray()); //仅保留指定集合中的元素 List<String> list3 = new ArrayList<String>(); list3.add("N"); list3.add("B"); a.retainAll(list2);/** *报java.util.ConcurrentModificationException * Collection / Map 对象实际只有一个元素的时候, * ConcurrentModificationException 异常并不会被抛出 */ a.removeAll(list3); a.add("D"); a.add("F"); //移除指定元素 a.remove("D"); //移除指定位置的元素 a.remove(1); } /** * 迭代集合元素两种不同方式 * @param list */ public static void printlist(List<String> list){ if(list != null && !list.isEmpty()){ //利用iterator()方法迭代集合 Iterator<String> it = list.iterator(); while(it.hasNext()){ System.out.println("itreator 迭代方式"+it.next()); } //利用ListItreator接口迭代 ListIterator listit = list.listIterator(); while(listit.hasNext()){ System.out.println("Listiterator 迭代方式"+listit.next()); } } } /** * 测试ListIterator接口迭代集合方式 */ public static void testListIterator(List<String> list){ ListIterator listit = list.listIterator(); //逆向遍历列表 while(listit.hasPrevious()){ System.out.println(listit.previous()); } } public static void main(String args[]){ List<String> colle1 = new ArrayList<String>(); colle1.add("G"); colle1.add("N"); colle1.add("GH"); List<String> colle2 = new ArrayList<String>(); colle2.add("N"); colle2.add("C"); //boolean flag = colle1.retainAll(colle2); //System.out.println(flag+" "+colle1 +" " +colle1.size()); List<String> list2 = colle1.subList(0, 1); boolean flag2 = colle1.retainAll(list2);//当元素只有一个时不会抛异常 System.out.println(flag2+" "+colle1 ); //basicTest(colle1,colle2); } }
运行程序时报了异常java.util.ConcurrentModificationException 这个异常大概的原因就是说非线程安全的集合在对集合进行删除的时候报的异常,网上的解释有很多。
sublist 方法源码:
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}
通过查看SubList类所抛出的异常并没有该异常,通过Debug调式得知该异常是由于每次在对集合进行修改的时候都会调用一个叫checkForComodification 方法抛出的异常,该方法主要是检测集合大小是否一致。
在AbstractCollection 的 retainAll 方法的源码:
public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> e = iterator(); while (e.hasNext()) { if (!c.contains(e.next())) { e.remove(); modified = true; } } return modified; }
retainAll 方法 是通过Iterator来移除操作不包含的元素,Iterator实现锁机制不存在不安全操作,然而引起该异常的真正原因是由于其作用是返回一个以fromIndex为起始索引(包含),以toIndex为终止索引(不包含)的子列表(List)
但值得注意的是,返回的这个子列表的幕后其实还是原列表;也就是说,修改这个子列表,将导致原列表也发生改变;反之亦然。也就是该原因导致该异常的出现