集合转数组:toArray()最优化方法探索

2021-09-24

优化背景

  • 有些场景下(比如入参要求)需要将集合(比如List)转为数组类型,利用集合的toArray方法应该最为方便的,对于toArray()无参方法其返回的是Object[],强制转其他类型数组会ClassCastException。推荐使用带参数的toArray(T[]),不过使用上需要注意

  • list强转数组抛异常-ClassCastException

 @Test
    //list强转数组抛异常-ClassCastException
    public void arrayError(){
        List<String> listToArray = new ArrayList<>();
        listToArray.add("jav");
        listToArray.add(0, "python");
        listToArray.add("php");
        listToArray.add("c#");
        String[] str = (String[]) listToArray.toArray();
        System.out.println(str);
    }

异常信息打印:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

  • 对于toArray()无参方法其返回的是Object[],正确写法
@Test
    //list转数组,使用object对象接受再循环遍历转出
    public void arrayObject(){
        List<String> listToArray = new ArrayList<>();
        listToArray.add("jav");
        listToArray.add(0, "python");
        listToArray.add("php");
        listToArray.add("c#");
        String[] s = new String[listToArray.size()];
        Object[] o = listToArray.toArray();
        for (int i = 0; i < o.length; i++) {
            s[i] = o[i].toString();
        }
        System.out.println(Arrays.toString(s));
    }

输出:[python, java, php, c#]

toArray(new String[0]), 创建一个大小为0的数组,当为输入数组长度小于集合size时,toArray方法会自动创建一个等大数组放入数据并返回。
toArray(new String[100000]),同上输入的10w数组比集合size小,toArray方法会重新创建一个等大数组放入数据并返回,原来的10w数组等于白建了
toArray(new String[1000000]),输入数组长度与集合size相等,当是一个理想状态时,即数组size没有发生变化(比如没有并发情况),那么toArray方法会直接使用输入数组并返回,但如果在输入数组创建之后,原集合size发生了变化,最糟糕的情况会退化为#2
toArray(new String[2000000]),输入数组长度大于集合size,那么toArray方法会直接使用输入数组并返回,当然多出去的那部分数组量就算浪费了

  • 最优化写法
@Test
    //list转数组-最优化写法
    public void OptimizeCode(){
        List<String> listToArray = new ArrayList<>();
        listToArray.add("jav");
        listToArray.add(0, "python");
        listToArray.add("php");
        listToArray.add("c#");
        String[] str = listToArray.toArray(new String[0]);
        System.out.println(Arrays.toString(str));
    }

输出:[python, java, php, c#]

  • 由此可以看出,如果在没有特殊需要的情况下,使用#1是比较高效的,也是大多数情况下比较推荐的写法