Java - Iterator和ListIterator

  • Iterator是所有Collection类(List、Set....)们都可以使用的迭代器,而ListIterator则是专门为List类所设计的迭代器

    • Iterator只支持hasNext()next()remove()三种操作,而ListIterator除了原本的3种之外,还支持了更多操作

      //Iterator接口
      public interface Iterator {
          boolean hasNext();
          E next();
          void remove();
      }
      //ListIterator接口
      public interface ListIterator extends Iterator {
          //继承自Iterator的接口
          boolean hasNext();         //后面是否有元素
          E next();                  //游标向后移动,取得后面的元素
          void remove();             //删除最后一个返回的元素
          
          //ListIterator新增的接口
          boolean hasPrevious();     //前面是否有元素
          E previous();              //游标往前移动,取得前面的元素
          int previousIndex();       //取得游标前的index
          int nextIndex();           //取得游标后的index
          void set(E e);             //将当前元素改设成e
          void add(E e);             //增加一个元素
      }
  • Iterator和ListIterator的差别

    • iterator()方法在所有集合类中都能使用,但是listIterator()只有List类能用

    • Iterator只能remove()元素,而ListIterator可以add()set()remove()

    • Iterator只能使用next()顺序的向后遍历,ListIterator则向前previous()和向后next()遍历都可以

      • 还有一个额外的功能,ListIterator可以使用nextIndex()previousIndex()取得当前游标位置的前后index位置,Iterator没有此功能

  • 如果想在遍历List时边做删除,用Iterator和ListIterator都能办到,但如果是想在遍历List时add元素,则只能使用ListIterator去做,因为Iterator是不提供此接口的

    • 要注意的是,边遍历List边使用Iterator和ListIterator的add()remove()时,并不会影响当前List输出结果,虽然他们修改的是同一个List,但是迭代器故意将add和remove设计成就算执行了,也不影响当前迭代器的输出结果

    public class Main {
        public static void main(String[] args) {
            List list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
    ​
            ListIterator it = list.listIterator();
    ​
            while (it.hasNext()) {
                Integer x = it.next();
                System.out.println(x);
                //虽然使用it.add(100)去新增一个元素,使得list实际储存的是 [1,2,100,3]
                //但是此处的遍历仍然只显示[1,2,3],这是迭代器故意这样设计的
                if (x == 2) {
                    it.add(100);
                }
            }
    ​
            System.out.println("list: " + list);
        }
    }
    1
    2
    3
    list: [1, 2, 100, 3]
  • 另外,虽然ArrayList和LinkedList都支持ListIterator,但通常只有在使用LinkedList时才会搭配ListIterator

    • 因为LinkedList几乎所有的时间消耗都是在去找到这个元素在哪,而找到此元素之后,对他进行修改是非常容易的事情(只要改指针就可以了),所以使用ListIterator的话,就可以节省下这个查找时间

    • 而对ArrayList来说,因为他查找的速度很快(底层是数组),因此使用ListIterator省下的查找时间非常少,所以对他来说,并没有迫切的需要使用ListIterator,使用add(index, E)也能达到同样的效率

    • 因此可以说ListIterator根本是为LinkedList发明的,ArrayList只是顺道实现而已,ArrayList去实现只是为了设计成让List接口的类们都能使用ListIterator而已

你可能感兴趣的:(Java)