A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 18353666072 中级黑马   /  2014-6-20 08:44  /  1977 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文



  1. import java.util.*;
  2. class ListDemo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                  method_2();
  7.         }
  8.         public static void method_2()
  9.         {
  10.                 ArrayList al = new ArrayList();
  11.                 al.add("day01");
  12.                 al.add("day02");
  13.                 al.add("day03");
  14.                 al.add("day04");
  15.                 sop(al);
  16.                 ListIterator li = al.listIterator();//
  17. 该接口只能通过List集合的listIterator方法获取这句话是什么意思 ,,
  18.                 while(li.hasNext())
  19.                 {
  20.                         Object obj = li.next();
  21.                         if(obj.equals("day03"))
  22.                         {
  23.                                 //li.add("day007");
  24.                                 li.set("java");
  25.                         }       
  26.                 }
  27.                 while(li.hasPrevious())
  28.                 {
  29.                         sop("pre="+li.previous());
  30.                 }
  31.                
  32.                 sop(al);
  33.         }
  34.         public static void sop(Object obj)
  35.         {
  36.                 System.out.println(obj);
  37.         }
  38. }
复制代码

ListIterator li = al.listIterator();// 该接口只能通过List集合的listIterator方法获取这句话是什么意思 ,为什么不用new了呢 为啥al.listIterator(); 就可以用了啊,,不理解,,还有Iterator lt= al.iterator();和上面的一样就是这句不一样,但是原理不一样,求大神解决一个,我就懂了 ,,,,,:handshake

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

4 个回复

倒序浏览
多看下JDK的文档就知道了, ArrayList的父类java.util.AbstractList<E>,而AbstractList<E>就有这个方法listIterator(),子类调用父类方法,不用new父类吧,所以就可以直接用了。
ListIterator<E>接口是Iterator<E>接口的子接口
系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间。长度为 n 的列表的迭代器有 n+1 个可能的指针位置,如下面的插入符举例说明:
回复 使用道具 举报
让我来带着楼主深入走进listIterator方法的方法体
接下来我跟你说的是JAVAlistIterator方法中的源码,他们是如何实现的
在看他们是如何实现的之前 我们先要看方法的含义 在JAVA文档中的介绍 :
    如下:返回在列表中的元素的列表迭代器(顺序)。此实现返回ListIterator(0)。
为什么要返回ListIterator因为需要被迭代便利的(说白了就是需要用的)元素种类很多ArrayList只是其中一种所以返回一个接口
然后我们要找到ListIterator方法所在的位置    位于      java.util.AbstractList.listIterator()
这个类的结构如下
class AbstractList<E> extends AbstractCollection<E> implements List<E>
方法体是这样的
public ListIterator<E> listIterator(final int index) {
        if (index<0 || index>size())
          throw new IndexOutOfBoundsException("Index: "+index);

        return new ListItr(index);
    }
刚才通过调用我发现index的值传入的时候是0固定的就是0加上final所以必定不会抛出异常而是走了new了一个ListItr类然后在构造中传入index  我们继续往下看ListItr类
ListItr
private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            cursor = index;
        }

在这里  他将0(索引)赋值给了游标,然后将这个已经有了游标的ListItr返回 ,现在 我们接收到的对象应该是一个实现了ListIterator并且继承了Itr 类的一个ListItr 对象    。接着程序往下走你看到这个对象调用了.hasnext()方法来判断是否有下个值
请看li.hasNext()的方法体
public boolean hasNext() {
            return cursor != size();
        }

还记得刚才我们传入的游标吗   ,调用之前 他已经把游标的值传入0了  所以这个cursor 必定为0    size()暂时不做介绍了  楼主只要知道他这里的size方法必定返回调用的集合的size就可以了 。所以现在断定0!=4  对吧   。自然会返回false  ,也就是说  这个集合中还有值  
所以接下来调用li.next()方法
next方法做重点介绍
public E next() {
            checkForComodification();
            try {
                E next = get(cursor);
                lastRet = cursor++;
                return next;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

进入next以后  首先会执行checkForComodification方法
final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

这个方法会检查是否有并发修改的情况 所以单独建立一个值
然后接着往下走cursor的值是0 代表取集合元素中第一个值
请看get方法的源码
public E get(int index) {
        RangeCheck(index);

        return (E) elementData[index];
    }


在取值之前 一定要先检查索引的值是不是已经到了最后一个   如果到了 就会发生异常
private void RangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(
                "Index: "+index+", Size: "+size);
    }

所以做了这样的异常界定超过之后就会抛出IndexOutOfBoundsException
然后  楼主肯定会好奇E的类型   明明你调用的是你自己写的类为什么会使E呢?  请看最上面对
class AbstractList<E> extends AbstractCollection<E> implements List<E>
已经对E进行了规范 。所以你的类型兼容E的类型
于是就把从E中取到的值进行返回也就是我们今天看到的ArrayList的迭代器大致远离
纯手打 跪求技术分 最好多给点

评分

参与人数 1技术分 +1 收起 理由
SyouRai_Tsk + 1

查看全部评分

回复 使用道具 举报
默认规定,你记得就好了,还有就是都说了是一个方法,当然要用调用的形式啊,要不然你以为要怎么才能new出来呢?
回复 使用道具 举报
这个的确有点绕,你查下API就知道,Iterator和listIterator都是接口,而且,都没有构造方法,没有构造方法,不能直接创建对象。也就是不能直接用new的原因。还是API,我们知道ArrayList是AbstractList的子类,而AbstractList的listIterator()方法返回的是listIterator接口类型对象,所以,可以用listIterator的对象引用,去引用这个返回的对象。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马