美文网首页Java面试相关
java面试Iterator相关

java面试Iterator相关

作者: pr0metheus | 来源:发表于2018-04-09 13:30 被阅读0次

    面试题目一:请问如下代码输出结果是什么?

        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("hello");
            list.add("world");
            list.add("helloworld");
            for (int i = 0; i < list.size(); i++) {
                list.remove(i);
            }
            System.out.println(list);
        }
    

    答案:会输出[world]。该题目考察的是集合底层是数组,对于集合的remove操作,底层是将被删除元素之后的所有元素往前移动一个位置。

    面试题目二:问如下程序能否正常执行?并说明为什么?

    public class IteratorTest {
    
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("hello");
            list.add("world");
            list.add("helloworld");
    
            for (Iterator<String> ite = list.iterator(); ite.hasNext();) {
                String next = ite.next();
                list.remove(next);
            }
        }
    }
    

    答案:该程序执行后会抛出ConcurrentModificationException,当使用迭代器对ArrayList进行迭代的时候,不能在迭代中使用list.remove方法来删除元素,否则会抛出ConcurrentModificationException异常。本质原因是当调用ite.iterator()方法后,会生成一个Iterator接口的实例对象,该对象内部维护一个变量ExpectedModCount,该变量的初始值是集合的modCount,在迭代进行中使用集合的remove方法的时候会导致modCount值+1而ExpectedModCount还是原先的值,调用ite.next()方法内部会对ExpectedModCountmodCount进行比较操作,如果不等就会抛出ConcurrentModficationException。

    面试题目三:如下程序能否正常执行

    public class IteratorTest {
    
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("hello");
            list.add("world");
            list.add("helloworld");
    
            for (Iterator<String> ite = list.iterator(); ite.hasNext();) {
                String next = ite.next();
                ite.remove(); //关键看此处
            }
            System.out.println(list.size());
        }
    }
    

    答案:能够正常执行, 在迭代过程中虽然不能使用集合ArrayList的remove操作或者add操作(会致使modCount改变的操作),但是使用迭代器自带的remove方法是可以的,ite.remove内部会对ExceptedModCount的值进行修正,所以在调用ite.next()方法的时候,ExceptedModCount == ModCount的判断结果为true,故不会导致抛出ConCurrentModificationException

    总结:

    • 不使用迭代器对ArrayList进行迭代的时候,可以使用remove等操作,原因是ArrayList并没有对modCount进行判断
    • 使用迭代器对ArrayList进行迭代的时候,不能使用ArrayList的remove等会致使modCount改变的操作,否则在调用迭代器的next方法时会抛出ConcurrentModificationException
    • 使用迭代器对ArrayList进行迭代的时候,可以使用迭代器自带的remove操作,因为Iterator中的remove方法会对ExpectedModCount的值进行修正,在调用迭代器的next方法时ExpectedModCountmodCount的比较结果为true,故不会导致抛出ConcurrentModificationException异常。

    相关文章

      网友评论

        本文标题:java面试Iterator相关

        本文链接:https://www.haomeiwen.com/subject/ahfihftx.html