-
《猖狂Java教材》第8章HashSet类与接口Iterator
添加时间:2013-5-14 点击量:《猖狂Java教材》第8章 Java凑集
1: 异常:Exception in thread main java.lang.IllegalStateException
其源代码如下:
1 import java.util.;
2 public class IteratorTest
3 {
4 public static void main(String[] args)
5 {
6 Collection books=new HashSet();
7 books.add(轻量级Java企业应用实战);
8 books.add(猖狂Java教材);
9 books.add(猖狂Android教材);
10 Iterator it=books.iterator();
11 while(it.hasNext()){
12 it.remove();
13 }
14 System.out.println(books);
15
16 }
17
18 }Edtiplus输出提示信息如下:
Exception in thread main java.lang.IllegalStateException
at java.util.HashMap¥HashIterator.remove(HashMap.java:910)
at IteratorTest.main(IteratorTest.java:12)HashMap¥HashIterator中的remove办法如下:
void remove()1 public void remove() {
2 if (current == null)
3 throw new IllegalStateException();
4 if (modCount != expectedModCount)
5 throw new ConcurrentModificationException();
6 Object k = current.key;
7 current = null;
8 HashMap.this.removeEntryForKey(k);
9 expectedModCount = modCount;
10 }如以上代码可知其激发异常的原因在于current==null( Entry<K,V> current; // current entry)
因为其是实现的Iterator接口,定位到Iterator接口中的remove办法,可以知道若是要调用Iterator遍历Collection对象元素删除某一个元素时,必须应用Object next()在前,
不然将激发此类异常。
remove()1 /
2 Removes the underlying collection the last element returned
3 by this iterator (optional operation). This method can be called
4 only once per call to {@link #next}. The behavior of an iterator
5 is unspecified if the underlying collection is modified while the
6 iteration is in progress in any way other than by calling this
7 method.
8
9 @throws UnsupportedOperationException if the {@code remove}
10 operation is not supported by this iterator
11
12 @throws IllegalStateException if the {@code next} method has not
13 yet been called, or the {@code remove} method has already
14 been called after the last call to the {@code next}
15 method
16 /
17 void remove();
2:异常:Exception in thread main java.util.ConcurrentModificationException
下面有两段代码此中首要的差别在于第14行代码中的参数的不合,具体见下:猜测一下哪个将激发以上异常?
1 import java.util.;
2 public class IteratorErrorTest
3 {
4 public static void main(String[] args)
5 {
6 Collection books=new HashSet();
7 books.add(轻量级Java企业应用实战);
8 books.add(猖狂Java教材);
9 books.add(猖狂Android教材);
10 Iterator it=books.iterator();
11 while(it.hasNext()){
12 String book=(String)it.next();
13 System.out.println(book);
14 //if(book.equals(猖狂Java教材)){
15 // book.remove(book);
16 //}
17 if(book.equals(猖狂Android教材)){
18 books.remove(book);
19 }
20
21 }
22 System.out.println(books);
23
24 }
25
26 }Editplus输出提示信息如下:
Exception in thread main java.util.ConcurrentModificationException
at java.util.HashMap¥HashIterator.nextEntry(HashMap.java:894)
at java.util.HashMap¥KeyIterator.next(HashMap.java:928)
at IteratorErrorTest.main(IteratorErrorTest.java:14)如上我将相干的代码列出:
remove(Object key)1 //HashMap中的remove(Object key)办法
2 public V remove(Object key) {
3 Entry<K,V> e = removeEntryForKey(key);
4 return (e == null ? null : e.value);
5 }removeMapping(Object o)nextEntry()1 //HashMapIterator中办法nextEntry()
2 final Entry<K,V> nextEntry() {
3 if (modCount != expectedModCount) //断定Iterator计数是否与凑集中个数相等
4 throw new ConcurrentModificationException();
5 Entry<K,V> e = next;
6 if (e == null)
7 throw new NoSuchElementException();
8
9 if ((next = e.next) == null) {
10 Entry[] t = table;
11 while (index < t.length && (next = t[index++]) == null)
12 ;
13 }
14 current = e;
15 return e;
16 }从上可以知道其激发异常的原因关键在于应用Collecting类中的remove()办法时只是改变了modCount凑集个数,然则对应的迭代器Iterator中的expectedModCount却没有批改。
其实在HashMap中类注释中已经注解:
<p>The iterators returned by all of this classs collection view methods
are <i>fail-fast</i>: if the map is structurally modified at any time after
the iterator is created, in any way except through the iterators own
<tt>remove</tt> method, the iterator will throw a
{@link ConcurrentModificationException}. Thus, in the face of concurrent
modification, the iterator fails quickly and cleanly, rather than risking
arbitrary, non-deterministic behavior at an undetermined time in the
future.以上的代码可以斗劲上方的HashMapIterator中的与HashMap中的remove()办法领会此中的差别。
关于IteratorErrorTest 中两个参数的产生不合的成果答案不是以上的申明。
将代码项目组批改如下:
view code1 //迭代输出所有的元素
2 while(it.hasNext()){
3 String book=(String)it.next();
4 System.out.println(book);
5
6 }其实我们可以看到“猖狂Java教材”是books中最后一个元素,删除“猖狂Java教材”时其迭代器Iterator已经接见到最后一个元素,及其Field:next已经为null,法度跳出全部轮回。
参考链接:http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html
文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》