Java - Iterator和ListIterator

  • Iterator是所有Collection類(List、Set....)們都可以使用的迭代器,而ListIterator則是專門爲List類所設計的迭代器

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

      //Iterator接口
      public interface Iterator<E> {
          boolean hasNext();
          E next();
          void remove();
      }
      //ListIterator接口
      public interface ListIterator<E> extends Iterator<E> {
          //繼承自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<Integer> list = new ArrayList<>();
            list.add(1);
            list.add(2);
            list.add(3);
    ​
            ListIterator<Integer> 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而已

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章