《猖狂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 == nullnull : 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 code

    1 //迭代输出所有的元素
    
    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

    文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
    分享到: