/**
* @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()方法刪除元素,所導致的迭代次數變化,對於迭代器對象本身而言是可以預知的!
只有兒子是親的,纔會讓進門! 啊哈哈哈哈!