• 集合一些方法陷阱


    一:asList  数组转ArrayList陷阱:

    asList() 源码:
    public static <T> List<T> asList(T... a) {
    return new ArrayList<T>(a);
    }
    private final E[] a;
    ArrayList(E[] array) {
    if (array==null)
    throw new NullPointerException();
    a = array;
    }
    分析:需要注意以下几点:
    (1)总所周知,泛型对应的是对象类型,所以 asList(),转ArrayList的时候,数组的元素不能是基本数据类型。
    (2) asList(),转换后的List不能进行add(),remove()等操作。返回一个受指定数组支持的固定大小的列表,对返回列表的更改会“直接写”到数组。
     
    public static void test1(){
            //1 asList(),转ArrayList的时候,数组的元素不能是基本数据类型。
            int i[]={11,22,33};  
            List intList=Arrays.asList(i);  
            System.out.println(intList.size());//结果:1,原因:asList将int i[] 当做了参数
        }
        
        public static void test2(){
            //2 asList(),转换后的List不能进行add(),remove()等操作。
            //原因:返回一个受指定数组支持的固定大小的列表,对返回列表的更改会“直接写”到数组。
            String s[]={"aa","bb","cc"};  
            List<String> sList=Arrays.asList(s);  
            sList.add("dd");//error
        }
    那么如何正确的将数组转ArraysList呢?
     
    public static void test3(){
            //方法一
            String s[]={"aa","bb","cc"};
            List<String> list1 = new ArrayList<String>(Arrays.asList(s));
            list1.remove(0);//ok
            
            //方法二:
            List<String> list2 = new ArrayList<String>(s.length);
            list2.addAll(Arrays.asList(s));
            list2.remove(0);//ok
            
            //方法三:
            List<String> list3 = new ArrayList<String>(s.length);
            Collections.addAll(list3, s);
            System.out.println(list3.remove(0));//ok
            
            //对于基本类型,可以使用apache commons-lang工具包
            int i[]={11,22,33};
            //先把基本类型转换一下,再用上面3种方法转换
            Integer[] ii = ArrayUtils.toObject(i);
            List<Integer> list4 = new ArrayList<Integer>(ii.length);
            Collections.addAll(list4, ii);//ok
        }  
    commons-lang3-3.1.jar 下还有许多类似的工具。如:
     
    二 list.toArray() 陷阱:
    //java中的强制类型转换只能转换单个对象,所以不能使用这样的代码将 toArray 返回的数组强转为 String[]
    String[] arr=(String[])list.toArray();//会出现java.lang.ClassCastException
    正确的用法:
    public static void test4(){
            String s[]={"aa","bb","cc"};
            List<String> list1 = new ArrayList<String>(Arrays.asList(s));
            
            String[] s1 = new String[list1.size()]; 
            list1.toArray(s1);
            System.out.println(Arrays.toString(s1));
        }  
    三  list.subList() 大陷阱:
     
    注意:
    (1)用此方法生成列表后,不要再去操作源列表(原因:可分析源码)
    (2)用此方法生成列表list1,对list1进行的add,remove,最终还是在操作源列表。
    看下面错误案例:
    清单1:
    public static void test6(){
            String s[]={"aa","bb","cc","dd","ee"};
            List<String> list1 = new ArrayList<String>(Arrays.asList(s));
            List<String> list2 = list1.subList(0, 1);
            System.out.println("list2 size: "+list2.size());
            
            list1.add("ff");
            System.out.println("list2 size: " + list2.size());//error
        } 
    结果: java.util.ConcurrentModificationException
     
    清单2:
    public static void test5(){
            String s[]={"aa","bb","cc","dd","ee"};
            List<String> list1 = new ArrayList<String>(Arrays.asList(s));
            
            List<String> list2 = list1.subList(0, 1);
            
            System.out.println("list1 size: "+list1.size());
            System.out.println("list2 size: "+list2.size());
            //用此方法生成列表list1,对list1进行的add,remove,最终还是在操作源列表。
            list2.add("ff");
            
            System.out.println("----操作list2-----"); 
            System.out.println("list1 size: "+list1.size()); 
            System.out.println("list2 size: "+list2.size());
        }  
    结果:
    list1 size: 5
    list2 size: 1
    ----操作list2-----
    list1 size: 6
    list2 size: 2  
     
    需要操作子列表,需要拷贝一份出来:
     
    清单3:
    public static void test7(){
            String s[]={"aa","bb","cc","dd","ee"};
            List<String> list1 = new ArrayList<String>(Arrays.asList(s));
            
            List<String> list2 = new ArrayList<String>(Arrays.asList(s));
            
            //拷贝一份出来
            list2.addAll(list1.subList(0, 1));
            
            System.out.println("list1 size: "+list1.size());
            System.out.println("list2 size: "+list2.size());
            list2.add("ff");
            
            System.out.println("----操作list2-----"); 
            System.out.println("list1 size: "+list1.size()); 
            System.out.println("list2 size: "+list2.size());
        }  
    结果:
    list1 size: 5
    list2 size: 6
    ----操作list2-----
    list1 size: 5
    list2 size: 7  
       
     
     
  • 相关阅读:
    nodejs MYSQL数据库执行多表查询
    【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演
    【BZOJ2693】jzptab 莫比乌斯反演
    【BZOJ2154】Crash的数字表格 莫比乌斯反演
    【BZOJ2242】[SDOI2011]计算器 BSGS
    【BZOJ2005】[Noi2010]能量采集 欧拉函数
    【BZOJ1408】[Noi2002]Robot DP+数学
    【BZOJ2045】双亲数 莫比乌斯反演
    【BZOJ2186】[Sdoi2008]沙拉公主的困惑 线性筛素数
    【BZOJ4176】Lucas的数论 莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/xiaozhuanfeng/p/9581648.html
Copyright © 2020-2023  润新知