Java中for循環

最近一直在學JavaSE基礎,對於for循環一直不是很熟練,通過反覆的學習與練習,總結出了一些筆記。java

本文介紹使用這種循環的具體方式,說明如何自行定義能被這樣遍歷的類,並解釋和這一機制的一些常見問題。數組

在Java程序中,要「逐一處理」――或者說,「遍歷」――某一個數組或Collection中的元素的時候,通常會使用一個for循環來實現(固然,用其它種類的循環也不是不能夠,只是不知道是由於for這個詞的長度比較短,仍是由於for這個詞的含義和這種操做比較配,在這種時候for循環比其它循環經常使用得多)。app

對於遍歷數組,這個循環通常是採起這樣的寫法:dom

1:遍歷數組的傳統方式學習

 /* 創建一個數組 */ int[] nums = {1 2 3 4}; /* 開始遍歷 */ for (int j = 0; j < nums.length; j++) { int i = integers[j]; System.out.println(i); }

而對於遍歷Collection對象,這個循環則一般是採用這樣的形式:spa

2:遍歷Collection對象的傳統方式
/* 創建一個Collection */ String[] strings = {"A" "B" "C" "D"}; Collection stringList = java.util.Arrays.asList(strings); /* 開始遍歷 */ for (Iterator itr = stringList.iterator(); itr.hasNext();) { Object str = itr.next(); System.out.println(str); }
3:遍歷數組的簡單方式的等價代碼
/* 創建一個數組 */ int[] integers = {1 2 3 4}; /* 開始遍歷 */ for (int 變量名甲 = 0; 變量名甲 < integers.length; 變量名甲++) { System.out.println(integers[變量名甲]); /* 依次輸出「1」、「2」、「3」、「4」 */ }

這裏的「變量名甲」是一個由編譯器自動生成的不會形成混亂的名字。code

而遍歷一個Collection的操做也就能夠採用這樣的寫法:orm

4:遍歷Collection的簡單方式
 /* 創建一個Collection */ String[] strings = {"A" "B" "C" "D"}; Collection list = java.util.Arrays.asList(strings); /* 開始遍歷 */ for (Object str : list) { System.out.println(str); /* 依次輸出「A」、「B」、「C」、「D」 */ }

這裏所用的for循環,則會在編譯期間被當作是這樣的形式:對象

5:遍歷Collection的簡單方式的等價代碼
 /* 創建一個Collection */ String[] strings = {"A" "B" "C" "D"}; Collection stringList = java.util.Arrays.asList(strings); /* 開始遍歷 */ for (Iterator 變量名乙 = list.iterator(); 變量名乙.hasNext();) { Object str = 變量名乙.next(); System.out.println(str); /* 依次輸出「A」、「B」、「C」、「D」 */ }

防止在循環體裏修改循環變量編譯器

在默認狀況下,編譯器是容許在第二種for循環的循環體裏,對循環變量從新賦值的。不過,由於這種作法對循環體外面的狀況絲毫沒有影響,又容易形成理解代碼時的困難,因此通常並不推薦使用。

Java提供了一種機制,能夠在編譯期間就把這樣的操做封殺。具體的方法,是在循環變量類型前面加上一個「final」修飾符。這樣一來,在循環體裏對循環變量進行賦值,就會致使一個編譯錯誤。藉助這一機制,就能夠有效的杜絕有意或無心的進行「在循環體裏修改循環變量」的操做了。

6:禁止從新賦值

 int[] integers = {1 2 3 4}; for (final int i : integers) { i = i / 2; /* 編譯時出錯 */ }

注意,這只是禁止了對循環變量進行從新賦值。給循環變量的屬性賦值,或者調用能讓循環變量的內容變化的方法,是不被禁止的。

7:容許修改狀態
Random[] randoms = new Random[]{new Random(1), new Random(2), new Random(3)}; for (final Random r : randoms) { r.setSeed(4); /* 將全部Random對象設成使用相同的種子 */ System.out.println(r.nextLong()); /* 種子相同,第一個結果也相同 */ }

循環變量的類型能夠和要被遍歷的對象中的元素的類型相同。例如,用int型的循環變量來遍歷一個int[]型的數組,用Object型的循環變量來遍歷一個Collection等。

8:使用和要被遍歷的數組中的元素相同類型的循環變量
int[] integers = {1 2 3 4}; for (int i : integers) { System.out.println(i); /* 依次輸出「1」、「2」、「3」、「4」 */ }
9:使用和要被遍歷的Collection中的元素相同類型的循環變量
Collection< String> strings = new ArrayList< String>(); strings.add("A"); strings.add("B"); strings.add("C"); strings.add("D"); for (String str : strings) { System.out.println(str); /* 依次輸出「A」、「B」、「C」、「D」 */ }

循環變量的類型能夠是要被遍歷的對象中的元素的上級類型。例如,用int型的循環變量來遍歷一個byte[]型的數組,用Object型的循環變量來遍歷一個Collection< String>(所有元素都是String的Collection)等。

10:使用要被遍歷的對象中的元素的上級類型的循環變量
String[] strings = {"A" "B" "C" "D"}; Collection< String> list = java.util.Arrays.asList(strings); for (Object str : list) { System.out.println(str);/* 依次輸出「A」、「B」、「C」、「D」 */ }

循環變量的類型能夠和要被遍歷的對象中的元素的類型之間存在能自動轉換的關係。J2SE 1.5中包含了「Autoboxing/Auto-Unboxing」的機制,容許編譯器在必要的時候,自動在基本類型和它們的包裹類(Wrapper Classes)之間進行轉換。所以,用Integer型的循環變量來遍歷一個int[]型的數組,或者用byte型的循環變量來遍歷一個Collection< Byte>,也是可行的。

11:使用能和要被遍歷的對象中的元素的類型自動轉換的類型的循環變量
int[] integers = {1 2 3 4}; for (Integer i : integers) { System.out.println(i); /* 依次輸出「1」、「2」、「3」、「4」 */ }

注意,這裏說的「元素的類型」,是由要被遍歷的對象的決定的――若是它是一個Object[]型的數組,那麼元素的類型就是Object,即便裏面裝的都是String對象也是如此。

相關文章
相關標籤/搜索