2010-01-16 24 views
3

Java代碼:轉化列表使用CollectionUtils拋出ArrayStoreException信息

Transformer TRANSFORM_TO_INTEGER = new Transformer() { 
    public Object transform(Object input) { 
     Integer i = new Integer((String) input); 
     return i; 
    } 
}; 

String begin = "1,2,3,4,5"; 
List strList = Arrays.asList(StringUtils.split(begin, ",")); 
CollectionUtils.transform(strList, TRANSFORM_TO_INTEGER); 

此代碼將拋出ArrayStoreException信息:

java.lang.ArrayStoreException 
at java.util.Arrays$ArrayList.set(Arrays.java:2360) 
at java.util.AbstractList$ListItr.set(AbstractList.java:488) 
at org.apache.commons.collections.CollectionUtils.transform(CollectionUtils.java:434) 

這是爲什麼?

回答

5

ArrayStoreException發生在嘗試存儲不正確類型的對象時被放入數組中。

代碼在幹什麼?

在給出的示例代碼中,CollectionUtil.transform方法需要一個Collection並執行就地變換元件,這意味着Object s的取出的原始Collection(如List)並放回的同樣的Collection

Transformer代碼需要String並將它轉換爲一個Integer - 這是這裏核心問題 - 當變換應用於對象的類型是變化。

可能會出現什麼問題?

如前所述,CollectionUtil.transform將使用給定Transformer並在Collection每個元素執行轉換,並將其存儲回原始Collection,這是strList

我懷疑是由Arrays.asList創建的List正在被String[]的支持,因爲這將是可能的是ArrayStoreException的來源。運行調試器證實,由於它支持String[5]。 (使用Eclipse,在Windows上的JRE 6上運行。)

這個例子說明了什麼?

這是一個很好的例子,它說明了泛型的缺乏使得代碼不能被寫入,因此在運行時會出現問題。如果代碼是用泛型編寫的(Apache Commons Collection支持它),這些類型的問題將在編譯時被捕獲。

底線 - 一個不能變換類型元件以List - 如果List包含String s時,Transformer.transform應僅返回String

可以做些什麼?

作爲替代,Google Collections具有Collections2.transform方法,它接受一個給定的Collection並返回由Function轉化的Collection

該方法支持泛型,因此它是類型安全的,事實上它返回一個新的Collection意味着類型可以通過轉換進行更改。

+1

它可以改爲使用'數組。 asList(xxx)',或'Arrays.asList(new Object [] {xxx})'。更好地使用泛型,這會使就地變換產生懷疑。放棄Apache公共收藏可能更好。 – 2010-01-16 03:22:06

+0

如果我使用JDK1.4,該怎麼辦 – jackysee 2010-01-28 04:16:15

1

Arrays.asList方法使用與新列表實例相同的提供數組作爲後備數組。該API代碼如下所示:

public static <T> List<T> asList(T... a) { 
    return new ArrayList<T>(a); 
} 

StringUtils.split的調用將創建傳遞給Arrays.asList方法String[]。這會將可以插入新列表實例的元素的類型限制爲僅限String對象。

CollectionUtils類支持2種不同類型的轉換:

  1. 代替轉型 -在這種情況下,輸入集合實例獲取與轉換後的值更新。所有的transform()變種屬於這一類。使用由數組支持的Collection類型(例如ArrayList)時,只有當轉換後的值與後備數組類型兼容時,轉換才能成功。 這解釋了您所看到的例外情況。

  2. 出地方改造 -在這種情況下,輸入集合永遠不會更新。而是將轉換後的值收集到單獨的收集實例中。所有的collect()變種都屬於第二類。 collect()方法的重載版本要麼接受輸出集合作爲參數,要麼沒有指定單獨的集合創建一個新的列表實例來收集轉換後的值。

基於您正試圖解決,你應該與第二類型的變換去調用collect()變種之一的情況。

相關問題