java 集合遍歷Iterator/foreach

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午9:17:34
*
*/

常用遍歷集合元素方式
兩種:
1、Iterator接口
2、foreach循環

Iterator接口

程序開發中經常需要遍歷集合元素,Java jdk 專門提供一接口iterator. 與Collection、Map接口主要用於存儲元素不同,iterator接口主要用於迭代訪問(即遍歷)Collection中的元素。因此iterator也被稱爲迭代器。

案例:

package com.stormwang.cycle;

import java.util.ArrayList;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午9:12:42
*
*/
/**
 * 練習使用迭代器    遍歷集合元素
 * */
public class IteratorDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayList arrayList = new  ArrayList<>();
        arrayList.add("day_1");
        arrayList.add("day_2");
        arrayList.add("day_3");
        arrayList.add("day_4");
        Iterator iterator =arrayList.iterator();//獲取Iterator對象
        while (iterator.hasNext()) {            //判斷ArrayList中是否存在下一個元素
            Object object = (Object) iterator.next();   //取出ArrayList集合中的元素
            System.out.println(object);

        }

    }

}

解釋代碼
遍歷過程如下:
1、首先調用ArrayList集合的iterator()方法獲得迭代器對象。
2、然後 hasNext()方法判斷集合中是否有下一個元素。
3、若存在; 則next()方法獲取元素。
否則: 說明已到達了集合末尾,停止遍歷元素。
注意:next()方法獲取元素時,必須保證獲取元素的存在,否則,回拋出NoSuchElementException .

需要特別說明的是:

當通過迭代器獲取ArrayList集合元素時,都會將這些元素當做Object類型看待,如果要得到特定類型的元素。需要進行強制類型轉換。

  • iterator迭代器對象在遍歷集合時,內部採用指針方式來跟蹤集合中的元素。
    這裏寫圖片描述
    hasNext()方法返回false時,終止迭代器。
  • 迭代器注意:
    在集合進行迭代過程中,不允許出現迭代器以外的對象操作。
    比如:
package com.stormwang.cycle;

import java.util.ArrayList;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午9:12:42
*
*/
/**
 * 練習使用迭代器    遍歷集合元素
 * */
public class IteratorDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayList arrayList = new  ArrayList<>();
        arrayList.add("day_1");
        arrayList.add("day_2");
        arrayList.add("day_3");
        arrayList.add("day_4");
        Iterator iterator =arrayList.iterator();//獲取Iterator對象
        while (iterator.hasNext()) {            //判斷ArrayList中是否存在下一個元素
            Object object = (Object) iterator.next();   //取出ArrayList集合中的元素
            System.out.println(object);

            arrayList.add("Java");  //出現迭代器以外的對象操作元素

        }

    }

}

我們看一下結果:
這裏寫圖片描述

因爲在迭代過程中。出現了迭代器以外的對象操作元素。
會拋出java.util.ConcurrentModificationException異常。

所以:
Iterator在迭代是,只能對元素進行獲取(next())和刪除(remove())操作。

下面來說說foreach循環:

雖然Iterator可以用來遍歷集合元素,但寫法上比價繁瑣,爲了簡化書寫,jdk5。0開始提供了foreach循環。foreach循環是一種更加簡潔的for循環,也稱爲增強for循環。

  • foreach循環用途:
    用於遍歷 : 數組 或 集合
  • 語法格式:for(容器中元素類型 臨時變量 : 容器變量 ){
    執行語句;
    }
  • 與for循環區別:
    不需要獲取容器的長度
    不需要根據索引訪問容器中的元素,但會自動遍歷容器中的每一個元素。
    沒有循環條件
    沒有迭代語句

先來看看用foreach循環編輯集合:

package com.stormwang.cycle;

import java.util.LinkedList;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午9:17:34
*
*/
public class ForEachDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LinkedList linkedList = new LinkedList<>();
        //增操作
        System.out.println("增加元素:");
        linkedList.add("stu1");
        linkedList.add("stu2");
        linkedList.add("stu3");
        linkedList.add("stu4");
        for (Object object : linkedList) {
            System.out.println(object);
        }
    }

}

結果:

這裏寫圖片描述

再來看看利用簡單的 for循環遍歷集合:

package com.stormwang.cycle;

import java.util.LinkedList;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午9:17:34
*
*/
public class ForEachDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LinkedList linkedList = new LinkedList<>();
        //增操作
        System.out.println("增加元素:");
        linkedList.add("stu1");
        linkedList.add("stu2");
        linkedList.add("stu3");
        linkedList.add("stu4");
        /*
        for (Object object : linkedList) {
            System.out.println(object);
        }*/
        int length ;
        length= linkedList.size();
        System.out.println(length);

        for(int i =0;i<length;i++) {
            System.out.println(linkedList.get(i));
        }
    }

}

運行結果:
這裏寫圖片描述

可以看到,運行結果一樣,但是foreach循環操作更簡單。

foreach遍歷集合的侷限性

方便的同時,有其侷限性:
在遍歷數組或者集合時,只能訪問集合裏元素,不能對其進行修改。接下來以一個String 類型的數組爲例進行演示:

package com.stormwang.cycle;
/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午11:44:55
*
*/
/**
 * foreach循環侷限性演示:
 * 不能修改元素
 * */
public class SpecialForeach {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] str = {"aaa","bbb","ccc"};
        for (String string : str) {
            string = "ddd";
        }
        System.out.println("foreach循環修改後的數組"+str[0]+", "+str[1]+", "+str[2]);
        //for循環遍歷叔祖
        for (int i = 0; i < str.length; i++) {
            str[i]  = "ddd";
        }
        System.out.println("for循環修改後的數組"+str[0]+", "+str[1]+", "+str[2]);
    }

}

看一下結果:

這裏寫圖片描述

foreach循環沒有改變數組元素,for循環改變。

解釋:

這裏寫圖片描述

這段代碼只是將臨時變量str指向了一個新的字符串,對數組元素沒有任何影響。

而for循環,可以通過索引的方式來引用數組中的元素並將其修改。

Iterator遍歷集合元素得坑(侷限性)!

首先給出結論:

結論:
     在Iterator迭代器對集合元素遍歷時,不允許其他對象引用自身的 remove()方法進行刪除!若想刪除,須用迭代器自身的remove()方法。否則會拋出異常。

用代碼來演示一下:

package com.stormwang.cycle;

import java.util.ArrayList;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午11:59:17
*
*/
/**
 * 迭代器Iterator在遍歷過程中remove()操作
 * 
 * */
public class SpecialIterator {

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList<>();
        //實現集合的增刪改查
        arrayList.add("hello!");
        arrayList.add("I am java!");
        arrayList.add("今天是11月3號!,我在圖書館學習!");
        arrayList.add("我也會很牛逼的對嗎!");
        arrayList.add(3, "我是指定位置插入的元素");

        //現在進行迭代
        Iterator iterator =arrayList.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            if (("hello!").equals(object)) {
                //注意:  使用arraylist對象的remove()方法
                arrayList.remove(object);
            }

        }
        System.out.println(arrayList);

    }

}

看看運行一下:

這裏寫圖片描述

拋出了異常!!!!
這個異常是迭代器對象拋出的。

原因:
集合中刪除了的元素,會導致迭代器預期的迭代次數發生改變,導致迭代器結果不準確!

那麼有什麼措施嗎?就不能刪除了是吧! 不不不,有的!

措施:

1、從業務邏輯上分析,只想將一個元素刪除,至於後面的元素不去管他們,則刪除該元素後,我們跳出循環,即 break ; 。

package com.stormwang.cycle;

import java.util.ArrayList;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午11:59:17
*
*/
/**
 * 迭代器Iterator在遍歷過程中remove()操作
 * 
 * */
public class SpecialIterator {

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList<>();
        //實現集合的增刪改查
        arrayList.add("hello!");
        arrayList.add("I am java!");
        arrayList.add("今天是11月3號!,我在圖書館學習!");
        arrayList.add("我也會很牛逼的對嗎!");
        arrayList.add(3, "我是指定位置插入的元素");

        //現在進行迭代
        Iterator iterator =arrayList.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            if (("hello!").equals(object)) {
                //注意:  使用arraylist對象的remove()方法
                arrayList.remove(object);
                break;
            }

        }
        System.out.println(arrayList);

    }

}

運行後:

這裏寫圖片描述

2、若需要在集合的迭代期間對集合的元素進行刪除,可使用迭代器自身的刪除方法。 即 iterator.remove()。

看一下代碼:

package com.stormwang.cycle;

import java.util.ArrayList;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 創建時間:2017年11月3日 下午11:59:17
*
*/
/**
 * 迭代器Iterator在遍歷過程中remove()操作
 * 
 * */
public class SpecialIterator {

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList<>();
        //實現集合的增刪改查
        arrayList.add("hello!");
        arrayList.add("I am java!");
        arrayList.add("今天是11月3號!,我在圖書館學習!");
        arrayList.add("我也會很牛逼的對嗎!");
        arrayList.add(3, "我是指定位置插入的元素");

        //現在進行迭代
        Iterator iterator =arrayList.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            if (("hello!").equals(object)) {
                //注意:  使用arraylist對象的remove()方法
                iterator.remove();
            }

        }
        System.out.println(arrayList);

    }

}

再來看看運行:

這裏寫圖片描述

這次在迭代器迭代期間刪除成功!

再次申明一下結論:


結論:    調用迭代器對象的remove()方法刪除元素,所導致的迭代次數變化,對於迭代器對象本身而言是可以預知的!



只有兒子是親的,纔會讓進門!  啊哈哈哈哈!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章