List 接口提供了subList方法,其作用是返回一个原列表的一个视图。对子列表的修改可以直接反馈到原列表中。
/**
*subList 只是原列表的一个视图
* @author zhangwei_david
* @version $Id: SubListDemo.java, v 0.1 2014年10月18日 下午8:50:33 zhangwei_david Exp $
*/
public class SubListDemo {
/**
*
* @param args
*/
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
System.out.println("原列表的内容: " + list);
List<String> subList = list.subList(0, list.size());
System.out.println("子列表的内容: " + subList);
list = Collections.unmodifiableList(list);
subList.add("C");
System.out.println("子列表的内容: " + subList);
System.out.println("原列表的内容: " + list);
System.out.println("子列表和原列表是否相等:" + subList.equals(list));
}
}
原列表的内容: [A, B]
子列表的内容: [A, B]
子列表的内容: [A, B, C]
原列表的内容: [A, B, C]
子列表和原列表是否相等:true
对子列表中的增加可以直接反馈到原列表中。
那么翻过来是否可以呢?我们看下面一个示例:
/**
*subList 只是原列表的一个视图
* @author zhangwei_david
* @version $Id: SubListDemo.java, v 0.1 2014年10月18日 下午8:50:33 zhangwei_david Exp $
*/
public class SubListDemo {
/**
*
* @param args
*/
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
System.out.println("原列表的内容: " + list);
List<String> subList = list.subList(0, list.size());
System.out.println("子列表的内容: " + subList);
subList.add("C");
System.out.println("子列表的内容: " + subList);
System.out.println("原列表的内容: " + list);
System.out.println("子列表和原列表是否相等:" + subList.equals(list));
// 修改原列表
list.add("D");
System.out.println("子列表的内容: " + subList);
}
}
结果是:
子列表的内容: [A, B]
子列表的内容: [A, B, C]
原列表的内容: [A, B, C]
子列表和原列表是否相等:true
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(Unknown Source)
at java.util.SubList.listIterator(Unknown Source)
at java.util.AbstractList.listIterator(Unknown Source)
at java.util.SubList.iterator(Unknown Source)
at java.util.AbstractCollection.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at com.cathy.demo.collections.SubListDemo.main(SubListDemo.java:34)
为什么会有并发修改的异常呢?
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}
public int size() {
checkForComodification();
return size;
}
private void checkForComodification() {
if (l.modCount != expectedModCount)
throw new ConcurrentModificationException();
}
至此我们可以发现在修改原列表后,使用size 方法出现了并发修改异常。
也就是原列表在生成子列表的时候,原列表是不能再被修改的