更多 Java 集合類(lèi)方面的文章厅克,請(qǐng)參見(jiàn)文集《Java 集合類(lèi)》
摘要: 阿里巴巴集團(tuán)推出的《阿里巴巴Java開(kāi)發(fā)手冊(cè)(正式版)》是阿里巴巴近萬(wàn)名開(kāi)發(fā)同學(xué)集體智慧的結(jié)晶赔退,以開(kāi)發(fā)視角為中心,詳細(xì)列舉如何開(kāi)發(fā)更加高效证舟、更加容錯(cuò)硕旗、更加有協(xié)作性,力求知其然女责,更知其不然漆枚,結(jié)合正反例,讓Java開(kāi)發(fā)者能夠提升協(xié)作效率抵知、提高代碼質(zhì)量墙基。
作為一個(gè) Java 開(kāi)發(fā)人員软族,我花了一天時(shí)間閱讀了這個(gè)開(kāi)發(fā)手冊(cè),摘要了一些對(duì)于我有用的知識(shí)點(diǎn)残制。記錄如下立砸,僅供參考。
集合處理
- 關(guān)于
hashCode
和equals
的處理初茶,遵循如下規(guī)則:
1) 只要重寫(xiě)equals
颗祝,就必須重寫(xiě)hashCode
。
2) 因?yàn)?Set
存儲(chǔ)的是不重復(fù)的對(duì)象恼布,依據(jù)hashCode
和equals
進(jìn)行判斷螺戳,所以Set
存儲(chǔ)的對(duì)象必須重寫(xiě)這兩個(gè)方法。
3) 如果自定義對(duì)象做為Map
的鍵折汞,那么必須重寫(xiě)hashCode
和equals
倔幼。
正例:String
重寫(xiě)了hashCode
和equals
方法,所以我們可以非常愉快地使用String
對(duì)象作為 key 來(lái)使用字支。
-
ArrayList
的subList
結(jié)果不可強(qiáng)轉(zhuǎn)成ArrayList
凤藏,否則會(huì)拋出ClassCastException
異常。
說(shuō)明:subList
返回的是ArrayList
的內(nèi)部類(lèi)SubList
堕伪,并不是ArrayList
,而是ArrayList
的一個(gè)視圖栗菜,對(duì)于SubList
子列表的所有操作最終會(huì)反映到原列表上欠雌。 - 在
subList
場(chǎng)景中,高度注意對(duì)原集合元素個(gè)數(shù)的修改疙筹,會(huì)導(dǎo)致子列表的遍歷富俄、增加、刪除均產(chǎn)生ConcurrentModificationException
異常而咆。 - 使用集合轉(zhuǎn)數(shù)組的方法霍比,必須使用集合的
toArray(T[] array)
,傳入的是類(lèi)型完全一樣的數(shù)組暴备,大小就是list.size()
悠瞬。
反例:直接使用toArray
無(wú)參方法存在問(wèn)題,此方法返回值只能是Object[]
類(lèi)涯捻,若強(qiáng)轉(zhuǎn)其它類(lèi)型數(shù)組將出現(xiàn)ClassCastException
錯(cuò)誤浅妆。
正例:
List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);
說(shuō)明:使用 toArray
帶參方法,入?yún)⒎峙涞臄?shù)組空間不夠大時(shí)障癌,toArray
方法內(nèi)部將重新分配內(nèi)存空間凌外,并返回新數(shù)組地址;如果數(shù)組元素大于實(shí)際所需涛浙,下標(biāo)為 [ list.size() ]
的數(shù)組元素將被置為 null
康辑,其它數(shù)組元素保持原值摄欲,因此最好將方法入?yún)?shù)組大小定義與集合元素個(gè)數(shù)一致。
- 使用工具類(lèi)
Arrays.asList()
把數(shù)組轉(zhuǎn)換成集合時(shí)疮薇,不能使用其修改集合相關(guān)的方法胸墙,它的add/remove/clear
方法會(huì)拋出UnsupportedOperationException
異常。
說(shuō)明:asList
的返回對(duì)象是一個(gè)Arrays
內(nèi)部類(lèi)惦辛,并沒(méi)有實(shí)現(xiàn)集合的修改方法劳秋。Arrays.asList
體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口胖齐,后臺(tái)的數(shù)據(jù)仍是數(shù)組玻淑。
String[] str = new String[] { "a", "b" };
List list = Arrays.asList(str);
第一種情況:list.add("c");
運(yùn)行時(shí)異常。
第二種情況:str[0]= "gujin";
那么 list.get(0)也會(huì)隨之修改呀伙。
- 不要在
foreach
循環(huán)里進(jìn)行元素的 remove/add 操作补履。remove 元素請(qǐng)使用Iterator
方式,如果并發(fā)操作剿另,需要對(duì)Iterator
對(duì)象加鎖箫锤。
反例
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if("1".equals(temp)){
a.remove(temp);
}
}
正例:
Iterator<String> it = a.iterator();
while(it.hasNext()){
String temp = it.next();
if(刪除元素的條件){
it.remove();
}
}
- 集合初始化時(shí),盡量指定集合初始值大小雨女。
- 使用
entrySet
遍歷Map
類(lèi)集合 KV谚攒,而不是keySet
方式進(jìn)行遍歷。
說(shuō)明:keySet
其實(shí)是遍歷了 2 次氛堕,一次是轉(zhuǎn)為Iterator
對(duì)象馏臭,另一次是從hashMap
中取出 key 所對(duì)應(yīng)的 value。而entrySet
只是遍歷了一次就把 key 和 value 都放到了 entry 中讼稚,效率更高括儒。
如果是 JDK8,使用Map.foreach
方法锐想。 - 合理利用好集合的有序性(sort)和穩(wěn)定性(order)帮寻,避免集合的無(wú)序性(unsort)和不穩(wěn)定性(unorder)帶來(lái)的負(fù)面影響。
說(shuō)明:穩(wěn)定性指集合每次遍歷的元素次序是一定的赠摇。有序性是指遍歷的結(jié)果是按某種比較規(guī)則依次排列的固逗。如:ArrayList
是 order/unsort;HashMap
是 unorder/unsort蝉稳;TreeSet
是 order/sort抒蚜。 - 利用
Set
元素唯一的特性,可以快速對(duì)一個(gè)集合進(jìn)行去重操作耘戚,避免使用List
的contains
方法進(jìn)行遍歷嗡髓、對(duì)比、去重操作收津。
引用:
【Java編碼規(guī)范】《阿里巴巴Java開(kāi)發(fā)手冊(cè)(正式版)》發(fā)布饿这!