返回信息流public static void main(String[] args)
{
LinkedList<Integer> t = new LinkedList<Integer>();
t.add(0);
t.add(1);
t.add(2);
t.add(3);
t.add(4);
t.add(5);
t.add(6);
Iterator<Integer> it = t.iterator();
while(it.hasNext())
{
int temp = it.next();
System.out.println(temp);
if(temp == 5)
{
t.add(999);
}
}
}
遍历是不能修改 请问应该怎么处理呢? 都说LinkedList在增加、删除时很好用 怎么用呀。。。
这是一条镜像帖。来源:北邮人论坛 / java / #21357同步于 2012/2/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
菜鸟问题 ConcurrentModificationException
MrK
2012/2/15镜像同步14 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
你在迭代过程中修改了LinkedList的结构,而Iterator的结构并没有同步相应改变,再执行next()就会出错
【 在 MrK (Mr.K) 的大作中提到: 】
: public static void main(String[] args)
: {
: LinkedList<Integer> t = new LinkedList<Integer>();
: t.add(0);
: t.add(1);
: t.add(2);
: t.add(3);
: t.add(4);
: t.add(5);
: t.add(6);
: Iterator<Integer> it = t.iterator();
: while(it.hasNext())
: {
: int temp = it.next();
: System.out.println(temp);
: if(temp == 5)
: {
: t.add(999);
: }
: }
: }
: 遍历是不能修改 请问应该怎么处理呢? 都说LinkedList在增加、删除时很好用 怎么用呀。。。
add之后break吧
【 在 MrK (Mr.K) 的大作中提到: 】
: public static void main(String[] args)
: {
: LinkedList<Integer> t = new LinkedList<Integer>();
: ...................
【 在 lastword 的大作中提到: 】
: add之后break吧
是的 我知道迭代时不能修改
但是我想要的效果是add之后继续遍历
就是把新增的内容放在表尾 然后继续遍历(而不是break出去或重新遍历) 有办法实现么?
可以换成ListIterator,然后调用迭代器的add方法,但只能插入到当前元素之后而不是末尾,迭代器只能操作相邻元素
遍历过程中不能用list的add方法,api上有写
【 在 MrK (Mr.K) 的大作中提到: 】
: 是的 我知道迭代时不能修改
: 但是我想要的效果是add之后继续遍历
: 就是把新增的内容放在表尾 然后继续遍历(而不是break出去或重新遍历) 有办法实现么?
: ...................
【 在 lastword 的大作中提到: 】
: 可以换成ListIterator,然后调用迭代器的add方法,但只能插入到当前元素之后而不是末尾,迭代器只能操作相邻元素
: 遍历过程中不能用list的add方法,api上有写
谢谢指点 现在暂时这样实现 问题可以解决 高手们有什么其他方法也请告诉我
public static void main(String[] args)
{
LinkedList<Integer> t = new LinkedList<Integer>();
t.add(0);
t.add(1);
t.add(2);
t.add(3);
t.add(4);
t.add(5);
t.add(6);
for(ListIterator<Integer> it = t.listIterator(); it.hasNext();)
{
int temp = it.next();
System.out.println(temp);
if(temp == 1)
{
it.add(11111);
it.previous();
}
if(temp == 5)
{
it.add(99999);
it.previous();
}
}
}
5楼的代码好像跟顶楼的需求不符合,因为新加的数字被加到了检测位置的后面,而不是最后
我觉得如果确实有“循环检测,根据需要在列表最后加入数据,并且新数据也要被检测到”的话,可以自己定义数据结构。
我简单写了一个,懒惰起见变量取值和权限都没计较了,就是一个大概的意思
public class TestLink {
public static void main(String[] args) {
new TestLink().run();
}
public void run() {
LinkDataList t = new LinkDataList();
t.add(0);
t.add(1);
t.add(2);
t.add(3);
t.add(4);
t.add(5);
t.add(6);
MyData temp = t.getFirst();
while(temp != null) {
System.out.println(temp);
if(temp.data == 1)
{
t.add(11111);
}
if(temp.data == 5)
{
t.add(99999);
}
if (temp.data == 11111) {
t.add(12345);
}
temp = temp.next;
}
System.out.println(t);
}
class LinkDataList{
LinkedList<MyData> list = new LinkedList<MyData>();
public void add(int value) {
MyData data = new MyData(value);
if (list.size() != 0) {
MyData last = list.getLast();
data.pre = list.getLast();
last.next = data;
}
list.add(data);
}
public MyData getFirst() {
if (list.size() == 0) {
return null;
}
return list.getFirst();
}
public String toString() {
return list.toString();
}
}
class MyData {
int data;
MyData pre;
MyData next;
public MyData(int data) {
this.data = data;
}
public String toString() {
return String.valueOf(data);
}
}
}
如果是符合5楼这种在检测位置插入数据的话,要有指针记录,用链表类拉链,或者在插入时手动拉链
反正就是用一种数据结构来存储数据前后位置,JDK的LinkedList.Entry没有开放出来,其实做的是一样的事情
但sun的考虑应该是不希望用户关心内部实现机制,只提供一种在增删上高效的存储数据结构
我的例子里对成员变量都是直接访问了,比较完善的做法是用方法封起来,不过我的懒得写了,要不粘过来的代码太多。
public void add(E e) {
checkForComodification();
try {
AbstractList.this.add(cursor++, e);
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
如果你在遍历的时候,修改了list,那么modCount就不等于expectedModCount,于是就抛了你那个错,主要还是这些list不是同步的