2016-12-02 93 views
2

假設我有一個名爲Importable的接口,它有多個實現,其中一個接口是ImportableImpl轉換List <Staging <Importable>>轉換爲List <Staging <ImportableImpl >> with java 8 stream

我有一個Staging類別的列表,它有一個通用類型:Importable

通過Java 8流,我想列表轉換:

List<Staging<Importable>> list1 

到一個列表:

List<Staging<ImportableImpl>> list2 

我已經肯定列表list1Staging<ImportableImpl>列表,以便沒有ClassCastException可以發生。 我不知道java是否授權使用泛型類型進行這種轉換。

我想嘗試這樣的事:

list1.stream() 
    .map(Staging::getImportable) // retrieve generic type 
    .map(ImportableImpl.class::cast) 
    .collect(Collectors.toList()) 

但有了這個,我會得到一個List<ImportableImpl>而不是List<Staging<ImportableImpl>>

+0

如何創建一個'Staging'對象? – BretC

+0

爲什麼你需要這樣做?也許你應該添加更多的方法到你的界面。 – flakes

回答

4

我真的不知道你不能把一個List<Staging<Importable>>List<Staging<ImportableImpl>>無論無論是在第一個列表你的嘗試的目的,但。這些類型是不可兌換的。

唯一合理的方式做到這一點(與警告,雖然)是:

@SuppressWarnings("unchecked") // if you are sure that all elements are ImportableImpl 
list.stream().map(i -> (Staging<ImportableImpl>) i).collect(Collectors.toList()); 

其中list的類型爲List<Staging<? extends Importable>>,而不是一個List<Staging<Importable>>


當然,它可以用一個方法引用寫成:

list.stream().map(Staging.class::<ImportableImpl>cast).collect(Collectors.toList()); 
0

它看起來對我說,你要創建一個新的臨時對象...

這個答案假定您可以通過使用new Staging<>(thing)創建Staging對象。這是你需要的嗎?

list1.stream() 
    .map(s -> new Staging<ImportableImpl>(s.getImportable())) 
    .collect(Collectors.toList()) 
+0

這是我選擇的解決方案,但我想知道是否有辦法在不創建新對象的情況下執行此操作。所有其他的舞臺區域都必須使用此解決方案重新設置。 –

+0

@louisamoros如果您確定Staging對象包含'ImportableImpl',則可以進行不安全的轉換,例如'.map(s - >(Staging )((Staging)s)))' – BretC

+0

@路易莎摩羅斯雖然我同意其他一些評論,但這是一件令人討厭的事情 – BretC

0

如果我得到這個權利不是你基本上只是想表達一下你的list1其實已經是List<Staging<ImportableImpl>>類型的列表。因此扔掉您的界面Importable提供的抽象。

由於在運行時沒有任何通用類型存在,您應該只能投射List<Staging<ImportableImpl>> list2 = (List) list1。這是一個未經檢查的演員(以原始形式作爲中間人),並將刪除類型系統提供的一些安全。如果有人將Staging<AnotherImportableImpl>類型的對象添加到list1,它可能會中斷。 使用像流這樣的花式構造不會改變這種情況。基本上你只是想告訴編譯器,你確定你知道它無法檢查的東西。

相關問題