本文研究的主要是Java中EnumMap代替序數(shù)索引的相關(guān)內(nèi)容,具體介紹如下。
學(xué)習(xí)筆記《Effective Java 中文版 第2版》
經(jīng)常會(huì)碰到使用Enum的ordinal方法來(lái)索引枚舉類型。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Herb { private final String name; private final Type type ; Herb(String name, Type type ) { this.name = name; this. type = type ; } @Override public String toString() { return name; } } |
現(xiàn)在假設(shè)有一個(gè)香草的數(shù)組,表示一座花園中的植物,你想要按照類型(一年生、多年生或者兩年生植物)進(jìn)行組織之后再將這些植物列出來(lái)。如果要這么做的話,需要構(gòu)建三個(gè)集合,每種類型一個(gè),并且遍歷整座花園,將每種香草放到相應(yīng)的集合中。有些程序員會(huì)將這些集合放到一個(gè)按照類型的序數(shù)進(jìn)行索引的數(shù)組來(lái)實(shí)現(xiàn)這一點(diǎn)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/ / Using ordinal() to index an array - DON'T DO THIS Herb[] garden = ... ; / / Indexed by Herb. Type .ordinal() Set <Herb>[] herbsByType = ( Set <Herb>[])new Set [Herb. Type .values().length]; for ( int i = 0 ; i<herbsByType.length; i + + ) { herbsByType[i] = new HashSet<Herb>(); } for (Herb h : garden) { herbsByType[h. type .ordinal()].add(h); } / / Print the results for ( int i = 0 ; i<herbsByType.length; i + + ) { System.out.printf( "%s: %s%n" , Herb. Type .values()[i], herbsByType[i]); } |
這種方法的確可行,但是隱藏著許多問(wèn)題。因?yàn)閿?shù)組不能與泛型兼容。程序需要進(jìn)行未受檢的轉(zhuǎn)換,并且不能正確無(wú)誤地進(jìn)行編譯。因?yàn)閿?shù)組不知道它的索引代表著什么,你必須手工標(biāo)注這些索引的輸出。但是這種方法最嚴(yán)重的問(wèn)題在于,當(dāng)你訪問(wèn)一個(gè)按照枚舉的序數(shù)進(jìn)行索引的數(shù)組時(shí),使用正確的int值就是你的職責(zé)了;int不能提供枚舉的類型安全。你如果使用了錯(cuò)誤的值,程序就會(huì)悄然地完成錯(cuò)誤的工作,或者幸運(yùn)的話就會(huì)拋出ArrayIndexOutOfBoundException異常。
java.util.EnumMap是一種非常快速的Map實(shí)現(xiàn)專門用于枚舉的鍵。
1
2
3
4
5
6
7
8
9
10
11
|
/ / Using an EnumMap to associate data with an enum Map <Herb. Type , Set <Herb>> herbsByType = new EnumMap<Herb. Type , Set <Herb>>(Herb. Type . class ); for (Herb. Type t : Herb. Type .values) herbsByType.put(t, new HashSet<Herb>()); for (Herb h : garden) herbsByType.get(h. type ).add(h); System.out.println(herbsByType); |
這段程序更簡(jiǎn)短,更清楚,也更安全,運(yùn)行速度方面可以與使用序數(shù)的程序相媲美。它沒(méi)有不安全的轉(zhuǎn)換;不必手工標(biāo)注出這些索引的輸出,因?yàn)橛成滏I知道如何將自身翻譯成可打印的字符串的枚舉;計(jì)算數(shù)組索引時(shí)也不可能出錯(cuò)。EnumMap在運(yùn)行速度方面之所以能與通過(guò)序數(shù)索引的數(shù)組相媲美,是因?yàn)镋numMap在內(nèi)部使用了這種數(shù)組。但是它對(duì)程序員隱藏了這種思想細(xì)節(jié),集Map的豐富功能和類型安全與數(shù)組的快速于一身。注意EnumMap構(gòu)造器采用鍵類型的Class對(duì)象:這是一個(gè)有限制的類型令牌(bounded type token),它提供了運(yùn)行時(shí)的泛型信息。
總結(jié)
以上就是本文關(guān)于Java中EnumMap代替序數(shù)索引代碼詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
原文鏈接:http://blog.csdn.net/chy555chy/article/details/53765939