優化背景

  • 有些場景下(比如入參要求)需要將集合(比如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是比較高效的,也是大多數情況下比較推薦的寫法