2012-03-07 52 views
2

我有一個函數,它的參數是:有沒有一種優雅的方式將列表<Double>轉換成列表<Number>?

myFn(String, List<Number>, List<Number>) 

調用函數列表的兩個對象,我想作爲函數的第二個和第三個參數來使用。我收到編譯錯誤:

The method myFn(String, List<Number>, List<Number>) in the type MyLib is not applicable for the arguments (String, List<Double>, List<Double>) 

有沒有簡單的方法來克服這一點?有沒有簡單的方法將Double列表轉換爲數字列表?

回答

9

你不能投List<Double>List<Number>,因爲下面的代碼會破壞你的List<Double>

List<Double> list = new List<Double>(); 
List<Number> list1 = list; // This does not work 
list1.add(new Integer(0)); 
Double d = list.get(0);// Hu-hoh you received an Integer, not a Double!! 
List<? extends Number> list2 = list; // This does work 

你可以做什麼,是改變

myFn(String, List<Number>, List<Number>) 

myFn(String, List<? extends Number>, List<? extends Number>) 
+1

胡皓你收到了upvote! – 2012-03-07 22:08:46

4

變化myFn定義​​ ,你可以把它作爲myFn(String, List<Double>, List<Double>, Double.class)

+2

我沒有看到需要將類添加到方法的末尾。 – McDowell 2012-03-07 11:54:11

+0

你說得對,沒必要。這取決於你是否想知道方法體中的真實類型。 – viliam 2012-03-07 12:03:32

1

如果你不能改變myFn方法,那麼作弊是一個選項:

private <returntype> myFnAdapter(String s , List<Double> l1Double, List<Double> l2Double) { 

    // the following lines do create warnings 
    // it's safe, because all list items always extend Number. 
    List l1TypeErased = l1Double; 
    List<Number> l1Number = l1TypeErased; 

    List l2TypeErased = l2Double; 
    List<Number> l2Number = l2TypeErased; 

    return myFn(s, l1Number, l2Number); 
} 

你應該會看到一些警告,僅此而已。但是我們知道我們獲得了Double的列表,並且這些列表的所有項目都擴展爲Number,所以它在運行時不會造成麻煩。只需添加一條評論來解釋類型刪除。將所有值複製到新列表中會更便宜。

+0

這不是一個壞習慣嗎?是的,它可以工作,但如果myFn修改了列表 – 2012-03-07 11:45:13

+0

感謝您的提示,它也允許結束ClassCastException。我增加了2行,現在如果'myFn'的簽名發生了變化,它應該是編譯時錯誤。當然,這很醜陋(根據需要不夠優雅)。它是不兼容列表的適配器。 – 2012-03-07 12:00:14

1

您可以使用

myFn(String, List<? extends Number>, List<? extends Number>) 

或調用函數與

myFn(String, (List) list1, (List) list2); // produces a warning. 
+1

這不是一個壞習慣嗎?是的,但它也允許以ClassCastException結束,如果myFn修改了列表 – 2012-03-07 11:45:41

+0

我假定開發人員知道即使編譯器沒有,也可以安全地調用此函數。我從來沒有看到使用'List '作爲它旁邊的無用恕我直言的好例子,所以我很難想象'myFn'的功能。 – 2012-03-07 11:50:04

1

你不能投集合這樣。 This Java tutorial爲您提供完整的解釋。

作爲一個解決方案,你在哪裏調用該方法只需要創建一個新的列表與雙榜作爲一個參數:

List<Double> doubleList = new ArrayList<Double>(); 

myFn(new ArrayList<Number>(doubleList)); 
1

如果你知道該列表將不會通過方法進行修改,只是使用

List<Number> unmodifiableView = Collections.unmodifiableList(doubleList); 

它在恆定時間運行並返回一個視圖。這是完全類型安全的,高效的和合法的 - 只要你知道列表不會被修改。

相關問題