java新特性之for循環(huán)最全的用法總結(jié)
1. 增強(qiáng)for概述
增強(qiáng)for循環(huán),也叫Foreach循環(huán),用于數(shù)組和容器(集合類(lèi))的遍歷。使用foreach循環(huán)遍歷數(shù)組和集合元素時(shí),無(wú)需獲得數(shù)組和集合長(zhǎng)度,無(wú)需根據(jù)索引來(lái)訪(fǎng)問(wèn)數(shù)組元素和集合元素,大大提高的效率,代碼也簡(jiǎn)潔不少。
2. Oracle官網(wǎng)的解釋
So when should you use the for-each loop? Any time you can. It really beautifies your code. Unfortunately, you cannot use it everywhere. Consider, for example, the expurgate method. The program needs access to the iterator in order to remove the current element. The for-each loop hides the iterator, so you cannot call remove. Therefore, the for-each loop is not usable for filtering. Similarly it is not usable for loops where you need to replace elements in a list or array as you traverse it. Finally, it is not usable for loops that must iterate over multiple collections in parallel. These shortcomings were known by the designers, who made a conscious decision to go with a clean, simple construct that would cover the great majority of cases.
所以你應(yīng)該什么時(shí)候使用for-each循環(huán)?任何時(shí)候都可以。這真的美化你的代碼。不幸的是,你不能在任何地方使用它。考慮這些情況,例如,刪除方法。為了移除當(dāng)前的元素,該程序需要訪(fǎng)問(wèn)迭代器。for-each循環(huán)隱藏了迭代器,所以你不能調(diào)用刪除功能。因此,for-each循環(huán)不適用于過(guò)濾元素。同樣當(dāng)遍歷集合或數(shù)組時(shí)需要替換元素的循環(huán)也是不適用的。最后,它不適用于多個(gè)集合迭代中并行循環(huán)使用。設(shè)計(jì)師應(yīng)該了解這些缺陷,有意識(shí)地設(shè)計(jì)一個(gè)干凈,簡(jiǎn)單的構(gòu)造,來(lái)避免這些情況。有興趣的可以查看官網(wǎng)的API,如果不知道怎么在官網(wǎng)找到API,請(qǐng)點(diǎn)擊打開(kāi)官網(wǎng)查看API方法。
3. 增強(qiáng)for格式
for(集合或者數(shù)組元素的類(lèi)型 變量名 : 集合對(duì)象或者數(shù)組對(duì)象){
引用變量名的java語(yǔ)句;
}
官網(wǎng)解釋?zhuān)?/strong>
for (TimerTask t : c)
t.cancel();
When you see the colon (:) read it as “in.” The loop above reads as “for each TimerTask t in c.” As you can see, the for-each construct combines beautifully with generics. It preserves all of the type safety, while removing the remaining clutter. Because you don't have to declare the iterator, you don't have to provide a generic declaration for it. (The compiler does this for you behind your back, but you need not concern yourself with it.)
大意為:
當(dāng)你看到冒號(hào)(:),它讀作“進(jìn)來(lái)?!鄙鲜鲅h(huán)讀作“把c中的每個(gè)TimerTask元素進(jìn)行遍歷?!闭缒闼吹降模琭or-each結(jié)構(gòu)完美的與泛型結(jié)合。它保留了所有類(lèi)型的安全性,同時(shí)去除剩余的混亂。因?yàn)槟悴槐芈暶鞯?,你不必為它提供一個(gè)泛型的聲明。 (編譯器在你背后已經(jīng)做了,你不需要關(guān)心它。)
簡(jiǎn)單體驗(yàn)下:
1. 增強(qiáng)for遍歷數(shù)組
package cn.jason01;
//增強(qiáng)for遍歷數(shù)組
public class ForTest01 {
public static void main(String[] args) {
int[] array={1,2,3};
for(int element: array){
System.out.println(element);
}
}
}
2.增強(qiáng)for遍歷集合
package cn.jason01;
import java.util.ArrayList;
public class ForTest {
public static void main(String[] args) {
// 泛型推斷,后面可以寫(xiě)可以不寫(xiě)String
ArrayList<String> array = new ArrayList();
array.add("a");
array.add("b");
array.add("c");
for (String string : array) {
System.out.println(string);
}
}
}
4. 增強(qiáng)for底層原理
先看代碼
package cn.jason01;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 增強(qiáng)for底層原理
*
* @author cassandra
* @version 1.1
*/
public class ForTest {
public static void main(String[] args) {
// 泛型推斷,后面可以寫(xiě)可以不寫(xiě)String.規(guī)范一些是要寫(xiě)上的。
ArrayList<String> array = new ArrayList();
// 添加元素
array.add("a");
array.add("b");
array.add("c");
// 增強(qiáng)for實(shí)現(xiàn)
System.out.println("----enhanced for----");
for (String string : array) {
System.out.println(string);
}
// 反編譯之后的效果,也就是底層實(shí)現(xiàn)原理
System.out.println("---reverse compile---");
String string;
for (Iterator iterator = array.iterator(); iterator.hasNext(); System.out.println(string)) {
string = (String) iterator.next();
}
// 迭代器實(shí)現(xiàn)
System.out.println("------Iterator------");
for (Iterator<String> i = array.iterator(); i.hasNext(); System.out.println(i.next())) {
}
// 普通for實(shí)現(xiàn)
System.out.println("-----general for-----");
for (int x = 0; x < array.size(); x++) {
System.out.println(array.get(x));
}
}
}
從上面代碼可以看出,底層是由迭代器實(shí)現(xiàn)的,增強(qiáng)for實(shí)際上是隱藏了迭代器,所以不用創(chuàng)建迭代器自然代碼簡(jiǎn)潔不少。這也是增強(qiáng)for推出的原因,就是為了減少代碼,方便遍歷集合和數(shù)組,提高效率。
注意:正因?yàn)樵鰪?qiáng)for隱藏了迭代器,所以用增強(qiáng)for遍歷集合和數(shù)組時(shí),要先判斷是否為null,否則會(huì)拋出空指針異常。原因很簡(jiǎn)單,底層需要用數(shù)組或者集合對(duì)象去調(diào)用iterator()方法去創(chuàng)建迭代器(Iterator迭代器是一個(gè)接口,所以要用子類(lèi)來(lái)實(shí)現(xiàn)),如果是null,肯定拋出異常。
5. 增強(qiáng)for的適用性以及局限性
1.適用性
適用于集合和數(shù)組的遍歷。
2.局限性:
①集合不能為null,因?yàn)榈讓邮堑鳌?/p>
②隱藏了迭代器,所以在遍歷集合時(shí)不能對(duì)集合進(jìn)行修改(增刪)。
③不能設(shè)置角標(biāo)。
6.增強(qiáng)for用法詳解
1.增強(qiáng)for在數(shù)組中用法
package cn.jason05;
import java.util.ArrayList;
import java.util.List;
/**
* 增強(qiáng)for用法
*
* @author cassandra
*/
public class ForDemo {
public static void main(String[] args) {
// 遍歷數(shù)組
int[] arr = { 1, 2, 3, 4, 5 };
for (int x : arr) {
System.out.println(x);
}
}
}
2.增強(qiáng)for在集合中用法
package cn.jason05;
import java.util.ArrayList;
import java.util.List;
/**
* 增強(qiáng)for用法
*
* @author cassandra
*/
public class ForDemo {
public static void main(String[] args) {
// 遍歷集合
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
for (String s : array) {
System.out.println(s);
}
// 集合為null,拋出NullPointerException空指針異常
List<String> list = null;
if (list != null) {
for (String s : list) {
System.out.println(s);
}
}
// 增強(qiáng)for中添加或修改元素,拋出ConcurrentModificationException并發(fā)修改異常
for (String x : array) {
if (array.contains("java"))
array.add(1, "love");
}
}
3.泛型與增強(qiáng)for完美結(jié)合
注意:必須要與泛型完美結(jié)合,不然還得手動(dòng)向下轉(zhuǎn)型
1.沒(méi)有泛型效果,不能使用增強(qiáng)for
Student類(lèi)
package cn.jason01;
public class Student {
private String name1;
private String name2;
public Student() {
super();
}
public Student(String name1, String name2) {
super();
this.name1 = name1;
this.name2 = name2;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
}
測(cè)試代碼
package cn.jason01;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test02 {
public static void main(String[] args) {
// 創(chuàng)建集合1
List list1 = new ArrayList();
list1.add("a");
list1.add("b");
list1.add("c");
// 創(chuàng)建集合2
List list2 = new ArrayList();
list2.add("d");
list2.add("e");
list2.add("f");
// 創(chuàng)建集合三
List list3 = new ArrayList();
// 遍歷第一和第二個(gè)集合,并添加元素到集合三
for (Iterator i = list1.iterator(); i.hasNext();) {
// System.out.println(i.next());
String s = (String) i.next();
for (Iterator j = list2.iterator(); j.hasNext();) {
// list2.add(new Student(s,j.next()));
String ss = (String) j.next();
list3.add(new Student(s, ss));
}
}
// 遍歷集合三,并輸出元素
Student st;
for (Iterator k = list3.iterator(); k.hasNext(); System.out
.println(new StringBuilder().append(st.getName1()).append(st.getName2()))) {
st = (Student) k.next();
}
}
}
上面的代碼如果去掉注釋的兩行代碼,程序就會(huì)報(bào)錯(cuò),因?yàn)榧蠜](méi)有聲明元素是什么類(lèi)型,迭代器自然也不知道是什么類(lèi)型。所以沒(méi)有泛型,那么就要向下轉(zhuǎn)型,只能用迭代器,不能用增強(qiáng)for。
2.泛型與增強(qiáng)for
泛型修改上面代碼
package cn.jason01;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 增強(qiáng)for和泛型完美結(jié)合
*
* @author cassandra
*/
public class Test03 {
public static void main(String[] args) {
// 創(chuàng)建集合1
List<String> list1 = new ArrayList<String>();
list1.add("a");
list1.add("b");
list1.add("c");
// 創(chuàng)建集合2
List<String> list2 = new ArrayList<String>();
list2.add("d");
list2.add("e");
list2.add("f");
// 創(chuàng)建集合三
List<Student> list3 = new ArrayList<Student>();
//// 遍歷第一和第二個(gè)集合,并添加元素到集合三
for (String s1 : list1) {
for (String s2 : list2) {
list3.add(new Student(s1, s2));
}
}
// 遍歷集合三,并輸出元素
for (Student st : list3) {
System.out.println(new StringBuilder().append(st.getName1()).append(st.getName2()));
}
}
}
4.List集合遍歷四種方法
Collection接口中有iterator()方法,返回的是Iterator類(lèi)型,有一個(gè)迭代器為Iterator。List中有l(wèi)istIterator()方法,所以多了一個(gè)集合器ListIterator,其子類(lèi)LinkedList、ArrayList、Vector都實(shí)現(xiàn)了List和Collection接口,所以都可以用兩個(gè)迭代器遍歷。
代碼測(cè)試
package cn.jason05;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* 這是List集合遍歷四種方法
*
* @author cassandra
*/
public class ForDemo01 {
public static void main(String[] args) {
// 創(chuàng)建集合
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
// 方法1,Iterator迭代器遍歷
Iterator<String> i = list.iterator();
while (i.hasNext()) {
String s = i.next();
System.out.println(s);
}
// 方法2,ListIterator迭代器遍歷集合
ListIterator<String> lt = list.listIterator();
while (lt.hasNext()) {
String ss = lt.next();
System.out.println(ss);
}
// 方法3,普通for遍歷集合
for (int x = 0; x < list.size(); x++) {
String sss = list.get(x);
System.out.println(sss);
}
// 方法4,增強(qiáng)for遍歷集合
for (String ssss : list) {
System.out.println(ssss);
}
}
}
5.Set集合遍歷2中方法
由于Set集合沒(méi)有g(shù)et(int index)方法,所以沒(méi)有普通for循環(huán),Set中沒(méi)有l(wèi)istIterator()方法,所以沒(méi)有ListIterator迭代器。所以只有兩種遍歷方式。
代碼測(cè)試
package cn.jason05;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class ForTest03 {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
// 方法1,Iterator迭代器遍歷集合
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 方法2,增強(qiáng)for遍歷集合
for (String s : set) {
System.out.println(s);
}
}
}
7.歸納總結(jié)
1.增強(qiáng)for的適用性以及局限性
適用性:適用于集合和數(shù)組的遍歷。
局限性:
①集合不能為null,因?yàn)榈讓邮堑鳌?/p>
②不能設(shè)置角標(biāo)。
③隱藏了迭代器,所以在遍歷集合時(shí)不能對(duì)集合進(jìn)行修改(增刪)。
2.在集合中增強(qiáng)for與泛型結(jié)合,才能發(fā)揮新特性的作用。
3.查看官網(wǎng)新特性挺重要的,要知其然還要知其所以然,了如心中,才能運(yùn)用自如。
以上這篇java新特性之for循環(huán)最全的用法總結(jié)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java新特性之Nashorn_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java中使用StackWalker和Stream API進(jìn)行堆棧遍歷
- Java基礎(chǔ)之多線(xiàn)程
- Java讀取本地json文件及相應(yīng)處理方法
- Java使用openOffice對(duì)于word的轉(zhuǎn)換及遇到的問(wèn)題解決
- Java中比較運(yùn)算符compareTo()、equals()與==的區(qū)別及應(yīng)用總結(jié)
- java源碼解析之String類(lèi)的compareTo(String otherString)方法
- Java11 發(fā)布前抓緊掌握這些新特性
相關(guān)文章
Java對(duì)List進(jìn)行排序的方法總結(jié)
在Java中,對(duì)List進(jìn)行排序是一項(xiàng)常見(jiàn)的任務(wù),Java提供了多種方法來(lái)對(duì)List中的元素進(jìn)行排序,本文將詳細(xì)介紹如何使用Java來(lái)實(shí)現(xiàn)List的排序操作,涵蓋了常用的排序方法和技巧,需要的朋友可以參考下2024-07-07
在SpringBoot項(xiàng)目中利用maven的generate插件
今天小編就為大家分享一篇關(guān)于在SpringBoot項(xiàng)目中利用maven的generate插件,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
Struts2實(shí)現(xiàn)單文件或多文件上傳功能
這篇文章主要為大家詳細(xì)介紹了Struts2實(shí)現(xiàn)單文件或多文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
request.getRequestURL()等方法得到路徑的區(qū)別及說(shuō)明
這篇文章主要介紹了request.getRequestURL()等方法得到路徑的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享
這篇文章主要介紹了java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置的代碼分享,本文中使用的是QQ在線(xiàn)接口,也可以使用新浪、淘寶等提供的在線(xiàn)接口,需要的朋友可以參考下2014-08-08
學(xué)習(xí)SpringMVC——國(guó)際化+上傳+下載詳解
本篇文章主要介紹了學(xué)習(xí)SpringMVC——國(guó)際化+上傳+下載,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。2016-12-12
Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能【經(jīng)典實(shí)例】
這篇文章主要介紹了Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能,結(jié)合具體實(shí)例形式分析了java正則查找、字符串遍歷、group分組相關(guān)操作技巧,需要的朋友可以參考下2017-04-04

