在Java開(kāi)發(fā)中询件,集合唆樊,可以說(shuō)使我們必然要使用到的一個(gè)框架。對(duì)集合的遍歷也是我么經(jīng)常要進(jìn)行的操作嘿辟,而遍歷操作又有多種,下面就對(duì)集合遍歷進(jìn)行以下總結(jié)英古。
一昙读、List、Set的遍歷
List與Set都繼承了Collection接口蛮浑,從某種程度上來(lái)說(shuō)可以將List和Set看作同一種類型,因此對(duì)于他們的遍歷方式也是相同的艺沼。
下面以List為例進(jìn)行講述
List<String> lists = new ArrayList<>();
lists.add("A");
lists.add("B");
lists.add("C");
lists.add("D");
lists.add("E");
lists.add("F");
方式一:
普通for循環(huán)
for (int i = 0; i < lists.size(); i++){
System.out.println(lists.get(i));
}
當(dāng)然這種方式對(duì)于Set集合是不適用的壮虫,因?yàn)镾et集合中并沒(méi)有g(shù)et index方法。
方式二:
for-each循環(huán)
for(String s : lists){
System.out.println(s);
}
對(duì)于這種方式的遍歷剩拢,是會(huì)存在一些問(wèn)題的饶唤。首先,每次遍歷集合類時(shí)办素,都需要寫(xiě)很多樣板代碼祸穷,對(duì)遍歷進(jìn)行改造也很麻煩,需要修改每一個(gè)for循環(huán)雷滚。并且這樣做也模糊了代碼的本意祈远,需閱讀完整個(gè)循環(huán)體才能理解這段代碼的意圖,無(wú)形當(dāng)中增加了時(shí)間成本车份。
方式三:
使用Iterator外部迭代
Iterator<String> iterator = lists.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
方式四:
使用Iterator迭代
for (Iterator iterator = lists.iterator(); iterator.hasNext();)
{
String string = (String) iterator.next();
}
實(shí)際上方式四和方式三是類似的,區(qū)別只不過(guò)是方式三使用while循環(huán)扫沼,方式四使用for循環(huán)庄吼。
并且從內(nèi)部來(lái)說(shuō)方式二(for-each循環(huán))與方式三以政、方式四(Iterator遍歷)其實(shí)是相同的,屬于外部迭代废菱,只是形式不同抖誉。for-each其實(shí)是一個(gè)封裝了迭代的語(yǔ)法糖。
但從性能上來(lái)說(shuō)袒炉,使用Iterator性能會(huì)更好些我磁。
總體上說(shuō),無(wú)論是for-each循環(huán)還是迭代器遍歷都會(huì)將行為和方法混為一談夺艰,很難抽象出各種不同的操作。
方式五:
Stream內(nèi)部迭代
List<String> lists = new ArrayList<String>();
lists.add("A");
lists.add("B");
lists.add("Ct");
lists.add("Dt");
lists.add("Et");
lists.add("Ft");
long count = lists.stream().filter(new Predicate<String>(){
@Override
public boolean test(String t){
return t.endsWith("t");
}
}).count();
System.out.println(count);
在這里我們過(guò)濾出以"t"結(jié)尾的字符串减牺,并打印出這樣字符串的個(gè)數(shù)存谎。
這是Java8新出來(lái)的一個(gè)類,Stream使用函數(shù)式編程的方式在集合類上進(jìn)行復(fù)雜操作的工具稚失。我們可以通過(guò)這種流機(jī)制恰聘、Stream類中的各種操作符以及Java中的函數(shù)接口去做任何我們想做的事情,并且代碼的可讀性也大大提高诫钓。
二篙螟、Map的遍歷
Map<Integer, String> maps = new HashMap<Integer, String>();
maps.put(1, "A");
maps.put(2, "B");
maps.put(3, "C");
maps.put(4, "D");
maps.put(5, "E");
方式一:
for-each單獨(dú)遍歷key和value
//遍歷keys
for(Integer key : maps.keySet()){
System.out.println(key);
}
//遍歷values
for(String value : maps.values()){
System.out.println(value);
}
方式二:
先遍歷keys问拘,然后通過(guò)key查找值
for(Integer key : maps.keySet()){
String value = maps.get(key);
System.out.println(key+":"+value);
}
方式三:
通過(guò)Entry進(jìn)行遍歷
for (Map.Entry<Integer, String> entry : maps.entrySet()){
Integer key = entry.getKey();//獲取key
String value = entry.getValue();//獲取value
System.out.println(key + ":" + value);
}
方式四:
使用迭代器進(jìn)行遍歷
Iterator<Map.Entry<Integer, String>> iterator = maps.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<Integer, String> entry = iterator.next();
Integer key = entry.getKey();//獲取key
String value = entry.getValue();//獲取value
}
四種遍歷方式的比較
在這四種方式中,方式二是效率最低的一種方式绪杏,因?yàn)閺膹逆I取值的get方法是耗時(shí)的操作,所以并不推薦使用此方式势似。
方式一在性能上比方式三要好一些僧著,并且方式一的代碼更加干凈易讀。
在性能方面盹愚,方式四與方式一可以說(shuō)是相同的皆怕。