List,Set,Map的两种初始化赋值方式

 List
List<Integer> list2 = new ArrayList<Integer>();
for (int i=0;i<times;i++){
list2.add(i);
} List<Integer> list1 = new ArrayList<Integer>(){
{
for (int i=0;i<times;i++){
add(i);
}
}
};
 Map
Map<String,String> map = new HashMap<String,String>(){
{
put("14","我是14");
put("13","我是13");
put("12","我是12"); }
};

Set

Set<String> set = new HashSet<String>(){
{
add("a");
add("b");
add("c");
}
};

两种方式中显然直接在申明时赋值的写法比较优雅,在List后面的两个{{}}的意义是,第一层括号表示一个匿名内部类,第二层括号表示在生成的内部类构造时被初始化,将class文件反编译后可以看出,java将匿名内部类创建了两个类,子类中含有父类的引用

源代码
public class MyTest2 {
Map<String,String> map = new HashMap<String,String>(){
{
put("1","我是1");
put("2","我是2");
}
};
public static int index = 10;
public static void main(String[] args) {
List<String> list = new ArrayList<String>(10){
{
for (int i=0;i<index;i++){
add("a");
}
}
};
}
}
反编译后:
public class MyTest2
{
Map<String, String> map = new HashMap() {};
public static int index = 10; public static void main(String[] args)
{
List<String> list = new ArrayList(10) {};
}
}
final class MyTest2$2
extends ArrayList<String>
{
MyTest2$2(int x0)
{
super(x0);
for (int i = 0; i < MyTest2.index; i++) {
add("a");
}
}
}
class MyTest2$1
extends HashMap<String, String>
{
MyTest2$1(MyTest2 this$0)
{
put("1", "我是1");
put("2", "我是2");
}
}
可知,编译后生成的实际上是ArrayList和HashMap的子类,因此有些操作是不允许的。
  1. 此种方式是匿名内部类的声明方式,所以引用中持有着外部类的引用。所以当时串行化这个集合时外部类也会被不知不觉的串行化,当外部类没有实现serialize接口时,就会报错。(序列化)
  2. 上例中,其实是声明了一个继承自HashMap的子类。然而有些串行化方法,例如要通过Gson串行化为json,或者要串行化为xml时,类库中提供的方式,是无法串行化Hashset或者HashMap的子类的,从而导致串行化失败。解决办法:重新初始化为一个HashMap对象(串行化)
List<String> list = new ArrayList<String>(){
{ for (int i=0;i<index;i++){
add("item"+i);
}
}
};
Gson gson = new Gson();
String str1 = gson.toJson(new ArrayList<String>(list));
若不重新赋值,打印出来的结果是null,重新赋值后打印出的结果是正确的。(经过测试,使用list.toString()是可以返回正确结果的)
执行效率方面
分别用两种方式初始化一个有一亿个元素的ArrayList,比较两者的时间
 
@Test
public void testEffict1(){
long start = System.currentTimeMillis();
int times = 1000000000;
List<Integer> list1 = new ArrayList<Integer>(){
{
for (int i=0;i<times;i++){
add(i);
}
}
};
long t1 = System.currentTimeMillis();
System.out.println("第一种方式time:"+(t1-start));
}
@Test
public void testEffict2(){
int times = 1000000000;
long t1 = System.currentTimeMillis();
List<Integer> list2 = new ArrayList<Integer>(100000000);
for (int i=0;i<times;i++){
list2.add(i);
}
long end = System.currentTimeMillis();
System.out.println("第二种方式time:"+(end-t1));
}
 
第一种方式time:33566
第二种方式time:33331

可见两者在效率方面的差别不大

Java中容器的两种初始化方式比较的更多相关文章

  1. Java中String对象两种赋值方式的区别

    本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...

  2. 细说java中Map的两种迭代方式

    曾经对java中迭代方式总是迷迷糊糊的,今天总算弄懂了.特意的总结了一下.基本是算是理解透彻了. 1.再说Map之前先说下Iterator: Iterator主要用于遍历(即迭代訪问)Collecti ...

  3. java中多线程的两种创建方式

    一丶继承Thread类实现多线程 第一步:继承Thread类第二步:重写run()方法第三步:创建继承了Thread类的对象 , 调用start()方法启动. //线程创建方式一 : /* 第一步:继 ...

  4. Java连载66-数组的两种初始化方式

    一.数组 1.数组中存储元素的类型是统一的,每一个元素在内存中所占用的空间大小是相同的,知道数组的首元素的内存地址,要查找的元素只要知道下标,就可以快速的计算出偏移量,通过首元素内存地址加上偏移量,就 ...

  5. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  6. 【转载】JAVA中线程的两种实现方法-实现Runnable接口和继承Thread类

    转自: http://blog.csdn.net/sunguangran/article/details/6069317 非常感谢原作者,整理的这么详细. 在java中可有两种方式实现多线程,一种是继 ...

  7. Springboot中IDE支持两种打包方式,即jar包和war包

    Springboot中IDE支持两种打包方式,即jar包和war包 打包之前修改pom.xml中的packaging节点,改为jar或者war    在项目的根目录执行maven 命令clean pa ...

  8. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

  9. JAVA中单例模式的几种实现方式

    1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...

随机推荐

  1. 关于cookie与session的理解

    服务器端并不能捕获客户端的浏览器关闭事件,因此你关闭浏览器以后,服务器端那个Session还是存在的,要超时以后才被回收,启动一个新的浏览器会启动一个新的session,所以他不认你了session永 ...

  2. webpack教程(二)——webpack.config.js文件

    首先我们需要安装一个webpack插件html-webpack-plugin,该插件的作用是帮助我们生成创建html入口文件.执行如下命令 npm install html-webpack-plugi ...

  3. web前端CSS2学习2017.6.17

    CSS---表现层,修饰和表现html文档,为了解决结构层和表现层分离的问题. 通过CSS极大的提高了工作效率,方便工作人员维护和管理CSS:层叠样式表,目前用的最广泛的css版本为css2,最新版本 ...

  4. SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

    SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...

  5. django-将数据库数据转换成JSON格式(ORM和SQL两种情况)

    最近打算搞一个自动化运维平台,所以在看Django的知识. 在实际项目开发中,遇到一个小问题:前后端发生数据交互主流采用的是JSON.前端传数据到服务器端比较简单,稍微麻烦的是服务器端传JSON到前端 ...

  6. Oracle 左连接 left join、右连接right join说明

    Oracle 左.右连接 + 在等号 左边表示右连接  获取右表所有记录,即使左表没有对应匹配的记录. + 在等号 右边表示左连接  获取左表所有记录,即使右表没有对应匹配的记录. 例子: selec ...

  7. BottomupSort算法 c++代码实现

    #include <iostream> using namespace std; #define N 100 int A[N]; static int n; void Initial() ...

  8. Socket 文件传输

    服务端 1.控件:TServerSocket 2.OnClientRead事件处理 procedure TMainForm.ssClientRead(Sender: TObject; Socket: ...

  9. Java读取property配置文件

    读取配置文件已经成了Java程序员工作的一项必备技能. 配置文件的优点: 可维护性好 怎么个可维护性好呢? 它会让程序中变化的地方很灵活的配置,不需要修改代码. Java程序部署到服务器上去之后就变成 ...

  10. windows调试工具列表

    摘自windbg帮助文档(windbg中输入.hh): Debugging Tools for Windows (安装WinDbg后这些工具都会安装在目录C:\Program Files (x86)\ ...