千万不要再这样创建集合了!极容易内存泄露!
共 9291字,需浏览 19分钟
·
2021-10-02 11:32
Set users = new HashSet();
users.add("Hollis");
users.add("hollis");
users.add("HollisChuang");
users.add("hollis666");
transferUsers(users);
这样的写法稍微有些复杂,有没有简洁的方式呢?
double-brace syntax
)建立并初始化一个新的集合:public class DoubleBraceTest {
public static void main(String[] args) {
Set users = new HashSet() {{
add("Hollis");
add("hollis");
add("HollisChuang");
add("hollis666");
}};
}
}
同理,创建并初始化一个HashMap的语法如下:
Map<String,String> users = new HashMap<>() {{
put("Hollis","Hollis");
put("hollis","hollis");
put("HollisChuang","HollisChuang");
}};
不只是Set、Map,jdk中的集合类都可以用这种方式创建并初始化。
javac DoubleBraceTest.java
我们会发现,得到两个class文件:
DoubleBraceTest.class
DoubleBraceTest$1.class
有经验的朋友可能一看到这两个文件就会知道,这里面一定用到了匿名内部类。
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");
}});
}});
}};
这会使得很多内部类被创建出来:
DoubleBraceTest$1$1$1.class
DoubleBraceTest$1$1$2.class
DoubleBraceTest$1$1.class
DoubleBraceTest$1.class
DoubleBraceTest.class
这些内部类被创建出来,是需要被类加载器加载的,这就带来了一些额外的开销。
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;
}
我们尝试通过调用getMap得到这样一个通过双括号初始化出来的map
public class DoubleBraceTest {
public static void main(String[] args) {
DoubleBraceTest doubleBraceTest = new DoubleBraceTest();
Map map = doubleBraceTest.getMap();
}
}
返回的Map现在将包含一个对DoubleBraceTest的实例的引用。读者可以尝试这通过debug或者以下方式确认这一事实。
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 的内部类,是一个原来数组的视图 List,因此如果对它进行增删操作会报错。
使用Stream
List<String> list1 = Stream.of("hollis", "Hollis", "HollisChuang").collect(Collectors.toList());
使用第三方工具类
ImmutableMap.of("k1", "v1", "k2", "v2");
ImmutableList.of("a", "b", "c", "d");
关于Guava和其中定义的不可变集合,我们后面会再详细介绍
Java 9内置方法
/**
* 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);
}
}
欢迎关注微信公众号:互联网全栈架构,收取更多有价值的信息。