Java中雙大括號初始化的理解與使用
偶然機會看到一種對象初始的方式:
// 新建一個列表,并賦值 "Harry","Tony","Tom"
ArrayList<String> friends = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
}};
當(dāng)然,對Map集合也用同種初始化方式:
// 新建一個Map,并賦值
Map<String, Object> cat = new HashMap<String, Object>() {{
put("name", "Tom");
put("age", 10);
}};
這里利用了內(nèi)部類語法,這種方式比先new出對象然后再進行依次add要方便、簡潔許多。該方法稱之為“雙括號初始化”(double brace initialization)。
對該方法的理解
以ArrayList的初始化為例,第一層花括號,首先對定義了一個繼承自ArrayList的匿名內(nèi)部類
ArrayList<String> friends = new ArrayList<String>() {
// 這里什么操作都沒有,全部繼承自父類(ArrayList)
};
第二層則是一個自定義的對象構(gòu)造塊(稱之為 非靜態(tài)初始化塊)
new ArrayList<String>() {
// 這里什么操作都沒有,全部繼承自父類(ArrayList)
};
我們通過new得到ArrayList的子類的實例化,然后上轉(zhuǎn)型為ArrayList的引用
ArrayList<String> friends = new ArrayList<String>() {{}};
- 我們得到的 friends 實際上是ArrayList的子類的引用,但在功能上沒有任何改變
- 相比于常規(guī)標準方式進行初始化要簡潔許多(但代碼可讀性相對會差)
效率問題
利用雙大括號初始化集合從效率上來說可能不如標準的集合初始化步驟。原因在于使用雙大括號初始化會導(dǎo)致內(nèi)部類文件的產(chǎn)生,而這個過程就會影響代碼的執(zhí)行效率。
首先查看不同初始化方式生成的.class文件
例如以下代碼:
public class Test1 {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
ArrayList<String> list1 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
ArrayList<String> list2 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
ArrayList<String> list3 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
ArrayList<String> list4 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
ArrayList<String> list5 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
……
…snip…
……
ArrayList<String> list1000 = new ArrayList<String>() {{
add("Harry");
add("Tony");
add("Tom");
add("Jerry");
}};
System.out.println(System.currentTimeMillis());
}
}
Test1編譯后生成的.class列表為:
Test1$1.class
Test1$2.class
Test1$3.class
Test1$4.class
Test1$5.class
……
…snip…
……
Test1$1000.class
Test1.class
生成了 1001個.class文件
public class Test2 {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
ArrayList<String> list1 = new ArrayList<>();
list1.add("Harry");
list1.add("Tony");
list1.add("Tom");
list1.add("Jerry");
ArrayList<String> list2 = new ArrayList<>();
list2.add("Harry");
list2.add("Tony");
list2.add("Tom");
list2.add("Jerry");
ArrayList<String> list3 = new ArrayList<>();
list3.add("Harry");
list3.add("Tony");
list3.add("Tom");
list3.add("Jerry");
ArrayList<String> list4 = new ArrayList<>();
list4.add("Harry");
list4.add("Tony");
list4.add("Tom");
list4.add("Jerry");
ArrayList<String> list5 = new ArrayList<>();
list5.add("Harry");
list5.add("Tony");
list5.add("Tom");
list5.add("Jerry");
……
…snip…
……
ArrayList<String> list1000 = new ArrayList<>();
list1000.add("Harry");
list1000.add("Tony");
list1000.add("Tom");
list1000.add("Jerry");
System.out.println(System.currentTimeMillis());
}
}
Test2編譯后生成的.class列表為:
Test2.class
只生成了1個.class文件
運行時間
第一段代碼Test1運行結(jié)果:
1508379452224
1508379452784
運行時間為:560毫秒
第二段代碼Test2運行結(jié)果:
1508379671505
1508379671507
運行時間為:2毫秒
雖然說這個時間差距會根據(jù)電腦性能以及運行狀態(tài)有所變化,但也能說明雙大括號初始化方法要比常規(guī)方法用時長
綜上,(測試初始化數(shù)據(jù)較少(list未達到自增臨界點)的情況下)雙大括號初始化方法要比常規(guī)方法效率低:
1. 雙大括號初始化方法生成的.class文件要比常規(guī)方法多
2. 雙大括號初始化方法運行時間要比常規(guī)方法長
總結(jié)
到此這篇關(guān)于Java中雙大括號初始化的理解與使用的文章就介紹到這了,更多相關(guān)Java雙大括號初始化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot+vue+Axios實現(xiàn)Token令牌的詳細過程
Token是在服務(wù)端產(chǎn)生的,前端可以使用用戶名/密碼向服務(wù)端請求認證(登錄),服務(wù)端認證成功,服務(wù)端會返回?Token?給前端,Token可以使用自己的算法自定義,本文給大家介紹SpringBoot+vue+Axios實現(xiàn)Token令牌,感興趣的朋友一起看看吧2023-10-10
SpringBoot詳解整合MyBatis過程中可能遇到的問題
因為Spring Boot框架開發(fā)的便利性,所以實現(xiàn)Spring Boot與數(shù)據(jù)訪問層框架(例如MyBatis)的整合非常簡單,主要是引入對應(yīng)的依賴啟動器,并進行數(shù)據(jù)庫相關(guān)參數(shù)設(shè)置即可2022-07-07
Java8新特性之lambda的作用_動力節(jié)點Java學(xué)院整理
我們期待了很久lambda為java帶來閉包的概念,但是如果我們不在集合中使用它的話,就損失了很大價值?,F(xiàn)有接口遷移成為lambda風(fēng)格的問題已經(jīng)通過default methods解決了,在這篇文章將深入解析Java集合里面的批量數(shù)據(jù)操作解開lambda最強作用的神秘面紗。2017-06-06
RepeatSubmit若依框架如何防止表單重復(fù)提交注解
若依框架中的@RepeatSubmit注解用于防止表單重復(fù)提交,通過在控制器方法上添加該注解,并在前端頁面和JavaScript代碼中實現(xiàn)雙重校驗,可以確保同一用戶在短時間內(nèi)不會重復(fù)提交相同的表單2024-11-11
Java中的System類、BigInteger類和BigDecimal類詳解
這篇文章主要介紹了Java中的System類、BigInteger類和BigDecimal類詳解,arraycopy()方法,復(fù)制數(shù)組元素,比較適合底層調(diào)用,一般使用Arrays.copyOf()完成復(fù)制數(shù)組,需要的朋友可以參考下2023-09-09

