優化背景

  • 有些場景下(比如入參要求)需要將集合(比如List)轉為陣列型別,利用集合的toArray方法應該最為方便的,對於toArray()無參方法其返回的是Object[],強制轉其他型別陣列會ClassCastException。推薦使用帶引數的toArray(T[]),不過使用上需要注意

  • list強轉陣列拋異常-ClassCastException

  1. @Test
  2. //list強轉陣列拋異常-ClassCastException
  3. public void arrayError(){
  4. List<String> listToArray = new ArrayList<>();
  5. listToArray.add("jav");
  6. listToArray.add(0, "python");
  7. listToArray.add("php");
  8. listToArray.add("c#");
  9. String[] str = (String[]) listToArray.toArray();
  10. System.out.println(str);
  11. }

異常資訊列印:

  1. java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
  • 對於toArray()無參方法其返回的是Object[],正確寫法
  1. @Test
  2. //list轉陣列,使用object物件接受再迴圈遍歷轉出
  3. public void arrayObject(){
  4. List<String> listToArray = new ArrayList<>();
  5. listToArray.add("jav");
  6. listToArray.add(0, "python");
  7. listToArray.add("php");
  8. listToArray.add("c#");
  9. String[] s = new String[listToArray.size()];
  10. Object[] o = listToArray.toArray();
  11. for (int i = 0; i < o.length; i++) {
  12. s[i] = o[i].toString();
  13. }
  14. System.out.println(Arrays.toString(s));
  15. }

輸出:[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方法會直接使用輸入陣列並返回,當然多出去的那部分陣列量就算浪費了

  • 最優化寫法
  1. @Test
  2. //list轉陣列-最優化寫法
  3. public void OptimizeCode(){
  4. List<String> listToArray = new ArrayList<>();
  5. listToArray.add("jav");
  6. listToArray.add(0, "python");
  7. listToArray.add("php");
  8. listToArray.add("c#");
  9. String[] str = listToArray.toArray(new String[0]);
  10. System.out.println(Arrays.toString(str));
  11. }

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

  • 由此可以看出,如果在沒有特殊需要的情況下,使用#1是比較高效的,也是大多數情況下比較推薦的寫法