由于Java語言的集合框架中(collections, 如list, map, set等)沒有提供任何簡便的語法結(jié)構(gòu),這使得在建立常量集合時(shí)的工作非常繁索。每次建立時(shí)我們都要做:
定義一個(gè)臨時(shí)的集合類變量 建立一個(gè)空集合的實(shí)例,然后賦值給變量 將數(shù)據(jù)放入集合中 最后將集合做為參數(shù)傳遞給方法
例如,要將一個(gè)Set變量傳給一個(gè)方法:
1
2
3
4
5
6
|
Set validCodes = new HashSet(); validCodes.add( "XZ13s" ); validCodes.add( "AB21/X" ); validCodes.add( "YYLEX" ); validCodes.add( "AR2D" ); removeProductsWithCodeIn(validCodes); |
也可以用靜態(tài)初始的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
private static final Set validCodes = new HashSet(); static { validCodes.add( "XZ13s" ); validCodes.add( "AB21/X" ); validCodes.add( "YYLEX" ); validCodes.add( "AR2D" ); } private static final Set validCodes = new HashSet(); static { validCodes.add( "XZ13s" ); validCodes.add( "AB21/X" ); validCodes.add( "YYLEX" ); validCodes.add( "AR2D" ); } |
其實(shí),還有簡結(jié)的方法,我們可以用雙括弧語法(double-brace syntax)建立并初始化一個(gè)新的集合:
1
2
3
4
5
6
7
8
9
10
11
12
|
private static final Set VALID_CODES = new HashSet() {{ add( "XZ13s" ); add( "AB21/X" ); add( "YYLEX" ); add( "AR2D" ); }}; private static final Set VALID_CODES = new HashSet() {{ add( "XZ13s" ); add( "AB21/X" ); add( "YYLEX" ); add( "AR2D" ); }}; |
或者
1
2
3
4
5
6
7
8
9
10
11
12
|
removeProductsWithCodeIn( new HashSet() {{ add( "XZ13s" ); add( "AB21/X" ); add( "YYLEX" ); add( "AR5E" ); }}); removeProductsWithCodeIn( new HashSet() {{ add( "XZ13s" ); add( "AB21/X" ); add( "YYLEX" ); add( "AR5E" ); }}); |
第一層括弧 實(shí)際是定義了一個(gè)內(nèi)部匿名類 (Anonymous Inner Class),第二層括弧 實(shí)際上是一個(gè)實(shí)例初始化塊 (instance initializer block),這個(gè)塊在內(nèi)部匿名類構(gòu)造時(shí)被執(zhí)行。這個(gè)塊之所以被叫做“實(shí)例初始化塊”是因?yàn)樗鼈儽欢x在了一個(gè)類的實(shí)例范圍內(nèi)。這和“靜態(tài)初始化塊 (static initialzer)”不同,因?yàn)檫@種塊在定義時(shí)在括弧前使用了static關(guān)鍵字,因此它的和類在同一個(gè)范圍內(nèi)的,也就是說當(dāng)類加載時(shí)就會(huì)被執(zhí)行
實(shí)例初始化塊中可以使用其容器范圍內(nèi)的所有方法及變量,但特別需要注意的是實(shí)例初始化塊是在構(gòu)造器之前運(yùn)行的。
這種方法只適用于不是final的類,因?yàn)閒inal類是無法建立內(nèi)部匿名子類,好在集合類都沒有這個(gè)限制。因此,這種方法還可以被用來初始化其它任何對(duì)象,比如一個(gè)GUI對(duì)象:
1
2
3
4
5
6
7
8
9
10
11
12
|
add( new JPanel() {{ setLayout(...); setBorder(...); add( new JLabel(...)); add( new JSpinner(...)); }}); add( new JPanel() {{ setLayout(...); setBorder(...); add( new JLabel(...)); add( new JSpinner(...)); }}); |
這樣建立的內(nèi)部匿名類的實(shí)例中包函它容器對(duì)像的引用。如果串行化(serialization)這個(gè)集合同時(shí)也會(huì)串行化它的內(nèi)部類。
另外,這種雙括號(hào)初始化的方式針對(duì)map的初始化工作可以減少很多代碼,請(qǐng)看:
1
2
3
4
5
6
7
8
9
10
11
|
Map<String, Set<String>> baselineMap = new HashMap<>(); final String schema = "schema" ; if (baselineMap.get(type) == null ) { baselineMap.put(type, new HashSet<String>() {{ add(schema); }}); } else { baselineMap.put(type, new HashSet<String>(baselineMap.get(type)) {{ add(schema); }}); } |
這段代碼我相信不用特別解釋,基本都能看懂,想想如果不用雙括號(hào)初始化的方式的話需要多寫多少行代碼!~
以上就是關(guān)于Java雙括弧初始化的技巧,提高了代碼的可讀性,而且簡化了代碼的數(shù)量,大家可以嘗試應(yīng)用到自己的項(xiàng)目中。