Algs4-1.3.50快速出错的迭代器
1.3.50快速出错的迭代器。修改Stack的迭代器代码,确保一旦用例在迭代器中(通过push()或pop()操作)修改集合数据就抛出一个java.util.ConcurrentModificationException异常。
解答:用一个计数器记录push()和pop()操作的次数。在创建迭代器时,将该值记录到Iterator的一个实例变量中。在每次调用hasNext()和next()之前,检查该值是否发生了变化,如果变化则抛出异常。
import java.util.Iterator;
public class Stack<Item> implements Iterable<Item>
{
private int N;
private Node first;
private int pushPopCount;
private class Node
{
Item item;
Node next;
}
public Stack()
{
}
public Stack(Stack s)
{
Node right=new Node();
Node oldright;
for(Object i:s)
{
oldright=right;
right=new Node();
right.item=(Item) i;
right.next=null;
if(isEmpty())
first=right;
else
oldright.next=right;
N++;
}
}
public boolean isEmpty()
{return N==0;}
public int size()
{return N;}
public void push(Item item)
{
Node oldfirst=first;
first=new Node();
first.item=item;
first.next=oldfirst;
N++;
pushPopCount++;
}
public Item pop()
{
Item item=first.item;
first=first.next;
N--;
pushPopCount++;
return item;
}
public Item peek()
{
Item item=first.item;
return item;
}
public void catenation(Stack s)
{
while(!s.isEmpty())
{
this.push((Item)s.pop());
}
}
public Iterator<Item> iterator()
{return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private Node current=first;
private int originatedPushPopCount;
public ListIterator()
{
originatedPushPopCount=pushPopCount;
}
public boolean hasNext(){return current!=null;}
public void remove(){}
public Item next()
{
if(originatedPushPopCount!=pushPopCount)
throw new java.util.ConcurrentModificationException();
Item item=current.item;
current=current.next;
return item;
}//end next
}//end class ListIterator
public static void main(String[] args)
{
Stack<String> s1=new Stack<String>();
In in1=new In(args[0]);
while(!in1.isEmpty())
{
String item=in1.readString();
s1.push(item);
}//end while
//
for(String item:s1)
{
StdOut.println(item+" ");
s1.push("push a element");
}
}
}
解答:用一个计数器记录push()和pop()操作的次数。在创建迭代器时,将该值记录到Iterator的一个实例变量中。在每次调用hasNext()和next()之前,检查该值是否发生了变化,如果变化则抛出异常。
import java.util.Iterator;
public class Stack<Item> implements Iterable<Item>
{
private int N;
private Node first;
private int pushPopCount;
private class Node
{
Item item;
Node next;
}
public Stack()
{
}
public Stack(Stack s)
{
Node right=new Node();
Node oldright;
for(Object i:s)
{
oldright=right;
right=new Node();
right.item=(Item) i;
right.next=null;
if(isEmpty())
first=right;
else
oldright.next=right;
N++;
}
}
public boolean isEmpty()
{return N==0;}
public int size()
{return N;}
public void push(Item item)
{
Node oldfirst=first;
first=new Node();
first.item=item;
first.next=oldfirst;
N++;
pushPopCount++;
}
public Item pop()
{
Item item=first.item;
first=first.next;
N--;
pushPopCount++;
return item;
}
public Item peek()
{
Item item=first.item;
return item;
}
public void catenation(Stack s)
{
while(!s.isEmpty())
{
this.push((Item)s.pop());
}
}
public Iterator<Item> iterator()
{return new ListIterator();}
private class ListIterator implements Iterator<Item>
{
private Node current=first;
private int originatedPushPopCount;
public ListIterator()
{
originatedPushPopCount=pushPopCount;
}
public boolean hasNext(){return current!=null;}
public void remove(){}
public Item next()
{
if(originatedPushPopCount!=pushPopCount)
throw new java.util.ConcurrentModificationException();
Item item=current.item;
current=current.next;
return item;
}//end next
}//end class ListIterator
public static void main(String[] args)
{
Stack<String> s1=new Stack<String>();
In in1=new In(args[0]);
while(!in1.isEmpty())
{
String item=in1.readString();
s1.push(item);
}//end while
//
for(String item:s1)
{
StdOut.println(item+" ");
s1.push("push a element");
}
}
}