zoukankan      html  css  js  c++  java
  • Java中容器的两种初始化方式比较

    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

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

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/andywithu/p/7239592.html
Copyright © 2011-2022 走看看