Java 陣列轉 List 的 3 種方式,哪種效能最牛?
前言:
本文介紹Java中陣列轉為List三種情況的優劣對比,以及應用場景的對比,以及程式設計師常犯的型別轉換錯誤原因解析。
一.最常見方式(未必最佳)
透過
Arrays。asList(strArray)
方式,將陣列轉換List後,不能對List增刪,只能查改,否則拋異常。
關鍵程式碼:
List list = Arrays。asList(strArray);
private
void
testArrayCastToListError
()
{
String
[]
strArray
=
new
String
[
2
];
List
list
=
Arrays
。
asList
(
strArray
);
//對轉換後的list插入一條資料
list
。
add
(
“1”
);
System
。
out
。
println
(
list
);
}
執行結果:
Exception
in
thread
“main”
java
。
lang
。
UnsupportedOperationException
at
java
。
util
。
AbstractList
。
add
(
AbstractList
。
java
:
148
)
at
java
。
util
。
AbstractList
。
add
(
AbstractList
。
java
:
108
)
at
com
。
darwin
。
junit
。
Calculator
。
testArrayCastToList
(
Calculator
。
java
:
19
)
at
com
。
darwin
。
junit
。
Calculator
。
main
(
Calculator
。
java
:
44
)
程式在list。add(“1”)處,丟擲異常:UnsupportedOperationException。
原因解析:
Arrays。asList(strArray)
返回值是
java。util。Arrays
類中一個私有靜態內部類
java。util。Arrays。ArrayList
,它並非
java。util。ArrayList
類。
java。util。Arrays。ArrayList
類具有 set(),get(),contains()等方法,但是不具有新增
add()
或刪除
remove()
方法,所以呼叫
add()
方法會報錯。
使用場景:
Arrays。asList(strArray)
方式僅能用在將陣列轉換為List後,不需要增刪其中的值,僅作為資料來源讀取使用。
二.陣列轉為List後,支援增刪改查的方式
透過ArrayList的構造器,將
Arrays。asList(strArray)
的返回值由
java。util。Arrays。ArrayList
轉為
java。util。ArrayList
。
關鍵程式碼:
ArrayList
private
void
testArrayCastToListRight
()
{
String
[]
strArray
=
new
String
[
2
];
ArrayList
<
String
>
list
=
new
ArrayList
<
String
>(
Arrays
。
asList
(
strArray
))
;
list
。
add
(
“1”
);
System
。
out
。
println
(
list
);
}
執行結果:成功追加一個元素“1”。
[null, null, 1]
使用場景:需要在將陣列轉換為List後,對List進行增刪改查操作,在List的資料量不大的情況下,可以使用。
三.透過集合工具類Collections.addAll()方法(最高效)
透過
Collections。addAll(arrayList, strArray)
方式轉換,根據陣列的長度建立一個長度相同的List,然後透過
Collections。addAll()
方法,將陣列中的元素轉為二進位制,然後新增到List中,這是最高效的方法。
關鍵程式碼:
ArrayList
<
String
>
arrayList
=
new
ArrayList
<
String
>(
strArray
。
length
);
Collections
。
addAll
(
arrayList
,
strArray
);
測試:
private
void
testArrayCastToListEfficient
(){
String
[]
strArray
=
new
String
[
2
];
ArrayList
<
String
>
arrayList
=
new
ArrayList
<
String
>(
strArray
。
length
);
Collections
。
addAll
(
arrayList
,
strArray
);
arrayList
。
add
(
“1”
);
System
。
out
。
println
(
arrayList
);
}
執行結果:同樣成功追加一個元素“1”。
[null, null, 1]
使用場景:需要在將陣列轉換為List後,對List進行增刪改查操作,在List的資料量巨大的情況下,優先使用,可以提高操作速度。
注:附上
Collections。addAll()
方法原始碼:
public
static
<
T
>
boolean
addAll
(
Collection
<?
super
T
>
c
,
T
。。。
elements
)
{
boolean
result
=
false
;
for
(
T
element
:
elements
)
result
|=
c
。
add
(
element
);
//result和c。add(element)按位或運算,然後賦值給result
return
result
;
}
問題解答
問題:陣列型別如果是整型陣列,轉為List時,會報錯?
答案:在
JDK1。8
環境中測試,這三種轉換方式是沒有問題的。放心使用。對於
Integer[]
整型陣列轉List的方法和測試結果如下:
方式一:不支援增刪
Integer
[]
intArray1
=
new
Integer
[
2
];
List
<
Integer
>
list1
=
Arrays
。
asList
(
intArray1
);
System
。
out
。
println
(
list1
);
執行結果:
[null, null]
方式二:支援增刪
Integer
[]
intArray2
=
new
Integer
[
2
];
List
<
Integer
>
list2
=
new
ArrayList
<
Integer
>(
Arrays
。
asList
(
intArray2
))
;
list2
。
add
(
2
);
System
。
out
。
println
(
list2
);
執行結果:
[null, null, 2]
方式三:支援增刪,且資料量大最高效
Integer
[]
intArray3
=
new
Integer
[
2
];
List
<
Integer
>
list3
=
new
ArrayList
<
Integer
>(
intArray3
。
length
);
Collections
。
addAll
(
list3
,
intArray3
);
list3
。
add
(
3
);
System
。
out
。
println
(
list3
);
執行結果:
[null, null, 3]
綜上,整型
Integer[]
陣列轉
List
的正確方式應該是這樣的。
易錯點:可能出現的錯誤可能是這樣轉換的:
int
[]
intArray1
=
new
int
[
2
];
List
<
Integer
>
list1
=
Arrays
。
asList
(
intArray1
);//
此處報錯
!!!
報錯原因:等號兩邊型別不一致,當然編譯不透過。分析見下文。
那麼在宣告陣列時,用
int[]
還是
Integer[]
,哪種宣告方式才能正確的轉為
List
呢?答案:只能用
Integer[]
轉
List
,即只能用基本資料型別的包裝型別,才能直接轉為
List
。
原因分析如下:
我們來看
List
在Java原始碼中的定義(別害怕看不懂原始碼,看我分析,很易懂的):
public
interface
List
<
E
>
extends
Collection
<
E
>
{
省略
…
}
再來看
Arrays。asList()
的在Java原始碼定義:
public
static
<
T
>
List
<
T
>
asList
(
T
。。。
a
)
{
return
new
ArrayList
<>(
a
);
}
從上述原始碼中可以看出,
List
宣告時,需要傳遞一個泛型
作為形參,
asList()
引數型別也是泛型中的通配型別
。Java中所有的泛型必須是引用型別。
什麼是引用型別?
Integer
是引用型別,那
int
是什麼型別?
int
是基本資料型別,不是引用型別。這就是為什麼java中沒有
List
,而只有
List
。
舉一反三:其他8種基本資料型別
byte、short、int、long、float、double、char
也都不是引用型別,所以8種基本資料型別都不能作為List的形參。但
String、陣列、class、interface
是引用型別,都可以作為List的形參,所以存在
List
介面型別的集合、
List
陣列型別的集合、
List
類的集合。但不存在
list
、
list
等基本型別的集合。
有了上述基礎知識後,再來看為什麼下面兩行程式碼第二行能編譯透過,第三行卻編譯報錯?
int
[]
intArray1
=
new
int
[
1
];
Arrays
。
asList
(
intArray1
);
//編譯不報錯
List
<
Integer
>
list1
=
Arrays
。
asList
(
intArray1
);//
編譯報錯
答案:
第二行程式碼,
Arrays。asList()
方法的入參是個引用型別的
int[]
,那麼返回值型別一定是
List
,其完整程式碼是:
List
,所以編譯透過,沒問題。
第三行報錯,因為等號兩邊的型別不一致,左邊:
List
,右邊
List
,所以編譯時就報錯。
總結
現在你應該明白,為什麼
int[]
不能直接轉換為
List
,而
Integer[]
就可以轉換為
List
了吧。
因為
List
中的泛型必須是引用型別,
int
是基本資料型別,不是引用型別,但
int
的包裝型別
Integer
是
class
型別,屬於引用型別,所以
Integer
可以作為
List
形參,
List
在java中是可以存在的,但不存在
List
型別。
在編碼時,我們不光要知其然,還要知其所以然,透過分析JDK原始碼,才能得出一手資訊,不僅瞭解到瞭如何用,還能得出為何這樣用。
希望我的解答對你有幫助,有疑惑的地方,可以在文章下方評論,我會給大家解惑的,喜歡本文請點贊和收藏。
原作者:大腦補丁
原文連結:
Java陣列轉List的三種方式及對比_五道口-CSDN部落格_陣列轉list
原出處:CSDN部落格
侵刪