1,HashMap 初始化的文艺写法
看完这段代码,很多人都会觉得这么写太啰嗦了,文艺青年一般这么来了:
看起来优雅了不少,一步到位,一气呵成的赶脚.然后问题来了,这里的双括号 "{{}}" 到底什么意思,什么用法呢?
HashMap map = new HashMap() {
{map.put("name", "test");
map.put("age", "20");
}
};
双括号 "{{}}", 用来初始化,使代码简洁易读.
第一层括弧实际是定义了一个匿名内部类 (Anonymous Inner Class),第二层括弧实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行.
2,推而广之,可初始化 ArrayList,Set
3,Java7:增加对 collections 的支持
List names = new ArrayList() {
{
for (int i = 0; i < 10; i++) {
add("A" + i);
}
}
};
System.out.println(names.toString());
在 Java 7 中你可以像 Ruby, Perl,Python 一样创建 collections 了, 但是这些集合是不可变的.
4,文艺写法的潜在问题
List list = ["item"];
String item = list[0];
Set set = {"item"};
Map map = {"key" : 1};
int value = map["key"];
文章开头提到的文艺写法的好处很明显就是一目了然.这里来罗列下此种方法的坏处,如果这个对象要串行化,可能会导致串行化失败.
1. 此种方式是匿名内部类的声明方式,所以引用中持有着外部类的引用.所以当时串行化这个集合时外部类也会被不知不觉的串行化,当外部类没有实现 serialize 接口时,就会报错.
2. 上例中,其实是声明了一个继承自 HashMap 的子类.然而有些串行化方法,例如要通过 Gson 串行化为 json,或者要串行化为 xml 时,类库中提供的方式,是无法串行化 Hashset 或者 HashMap 的子类的,从而导致串行化失败.解决办法:重新初始化为一个 HashMap 对象:
new HashMap(map);
这样就可以正常初始化了.
5,执行效率问题
当一种新的工具或者写法出现时,猿们都会来一句:性能怎么样?(这和男生谈论妹纸第一句一般都是:"长得咋样?三围多少?" 一个道理:))
关于这个两种写法我这边笔记本上测试文艺写法,普通写法分别创建 10,000,000 个 Map 的结果是 1217,1064,相差 13%.
public class Test {
public static void main(String[] args) {
long st = System.currentTimeMillis();
/*
for (int i = 0; i < 10000000; i++) {
HashMap map = new HashMap() {
{
put("name", "test");
put("age", "20");
}
};
}
System.out.println(System.currentTimeMillis() - st); // 1217
*/
for (int i = 0; i < 10000000; i++) {
HashMap map = new HashMap();
map.put("name", "test");
map.put("age", "20");
}
System.out.println(System.currentTimeMillis() - st); // 1064
}
}
来源: http://blog.csdn.net/yueguanyun/article/details/79216998