千萬不要再這樣創(chuàng)建集合了!極容易內(nèi)存泄露!

Set users = new HashSet();
users.add("Hollis");
users.add("hollis");
users.add("HollisChuang");
users.add("hollis666");
transferUsers(users);
這樣的寫法稍微有些復(fù)雜,有沒有簡潔的方式呢?
double-brace syntax)建立并初始化一個新的集合:public class DoubleBraceTest {
public static void main(String[] args) {
Set users = new HashSet() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("hollis666");
}};
}
}
同理,創(chuàng)建并初始化一個HashMap的語法如下:
Map<String,String> users = new HashMap<>() {{
put("Hollis","Hollis");
put("hollis","hollis");
put("HollisChuang","HollisChuang");
}};
不只是Set、Map,jdk中的集合類都可以用這種方式創(chuàng)建并初始化。
javac DoubleBraceTest.java
我們會發(fā)現(xiàn),得到兩個class文件:
DoubleBraceTest.class
DoubleBraceTest$1.class
有經(jīng)驗的朋友可能一看到這兩個文件就會知道,這里面一定用到了匿名內(nèi)部類。
Map hollis = new HashMap(){{
put("firstName", "Hollis");
put("lastName", "Chuang");
put("contacts", new HashMap(){{
put("0", new HashMap(){{
put("blogs", "http://www.hollischuang.com");
}});
put("1", new HashMap(){{
put("wechat", "hollischuang");
}});
}});
}};
這會使得很多內(nèi)部類被創(chuàng)建出來:
DoubleBraceTest$1$1$1.class
DoubleBraceTest$1$1$2.class
DoubleBraceTest$1$1.class
DoubleBraceTest$1.class
DoubleBraceTest.class
這些內(nèi)部類被創(chuàng)建出來,是需要被類加載器加載的,這就帶來了一些額外的開銷。
public Map getMap() {
Map hollis = new HashMap(){{
put("firstName", "Hollis");
put("lastName", "Chuang");
put("contacts", new HashMap(){{
put("0", new HashMap(){{
put("blogs", "http://www.hollischuang.com");
}});
put("1", new HashMap(){{
put("wechat", "hollischuang");
}});
}});
}};
return hollis;
}
我們嘗試通過調(diào)用getMap得到這樣一個通過雙括號初始化出來的map
public class DoubleBraceTest {
public static void main(String[] args) {
DoubleBraceTest doubleBraceTest = new DoubleBraceTest();
Map map = doubleBraceTest.getMap();
}
}
返回的Map現(xiàn)在將包含一個對DoubleBraceTest的實例的引用。讀者可以嘗試這通過debug或者以下方式確認(rèn)這一事實。
Field field = map.getClass().getDeclaredField("this$0");
field.setAccessible(true);
System.out.println(field.get(map).getClass());
使用Arrays工具類
List<String> list2 = Arrays.asList("hollis ", "Hollis", "HollisChuang");
但是需要注意的是,asList 得到的只是一個 Arrays 的內(nèi)部類,是一個原來數(shù)組的視圖 List,因此如果對它進(jìn)行增刪操作會報錯。
使用Stream
List<String> list1 = Stream.of("hollis", "Hollis", "HollisChuang").collect(Collectors.toList());
使用第三方工具類
ImmutableMap.of("k1", "v1", "k2", "v2");
ImmutableList.of("a", "b", "c", "d");
關(guān)于Guava和其中定義的不可變集合,我們后面會再詳細(xì)介紹
Java 9內(nèi)置方法
/**
* Returns an unmodifiable list containing zero elements.
*
* See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @return an empty {@code List}
*
* @since 9
*/
static <E> List<E> of() {
return ImmutableCollections.emptyList();
}
static <E> List<E> of(E e1) {
return new ImmutableCollections.List12<>(e1);
}
static <E> List<E> of(E... elements) {
switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.emptyList();
case 1:
return new ImmutableCollections.List12<>(elements[0]);
case 2:
return new ImmutableCollections.List12<>(elements[0], elements[1]);
default:
return new ImmutableCollections.ListN<>(elements);
}
}
