集合轉數組:toArray()最優化方法探索
優化背景
-
有些場景下(比如入參要求)需要將集合(比如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#]
- 另外
T[] toArray(T[] a); - 解決方案://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#toArray-T:A-
輸入參數為對應類型數組,那麼應該建立多大的數組作為參數呢,推薦為0,例如我們的有一個List包含100w的數據
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是比較高效的,也是大多數情況下比較推薦的寫法