2017-01-06 36 views
1

有關設置,我有:泛型參數返回列表<ChildInterface>在流,但直接的方法調用返回列表<Parent>

interface Parent 

interface Child1 extends Parent 

interface Child2 extends Parent 

和其他地方,我有:

public class MyClass { 
    private List<Child1> child1List = new ArrayList<>(); 

    public List<Parent> getChild1List(Contact contact) { 
     return child1List.parallelStream() 
         .filter(m -> m.getContacts().contains(contact)) 
         .sorted(Comparator.comparing(Parent::getParentField)) 
         .collect(Collectors.toList()); 
    } 
} 

當我做這個方式,getChild1List返回一個List<Parent>(不應該它返回List<Child1>?)

後來,我發現流是有用的其他方法,所以我分機對它進行了檢查並建立了一個通用的方法。我有一個擴展父多個接口,所以我也如下:

private <T extends Parent> List<T> returnsListByContact(List<T> childList, Contact contact) { 
     return childList.parallelStream() 
         .filter(m -> m.getContacts().contains(contact)) 
         .sorted(Comparator.comparing(Parent::getParentField)) 
         .collect(Collectors.toList()); 
    } 

getChild1List(Contact contact)變成了:

public List<Parent> getChild1List(Contact contact) { 
     return returnsListByContact(child1List, contact); 
    } 

但現在不喜歡這個,理由是getChild1List返回一個List<Child1>。我不明白爲什麼,因爲流的實現根本沒有改變 - 除了啓動它的childList來自通用參數,而不是直接調用MyClass的私有成員字段。

那麼,爲什麼他們返回兩個不同的東西?

+1

我修正了格式。對內聯代碼使用反引號,並用四個空格縮進來格式化代碼塊。如果您希望代碼顯示四個空格的縮進,則必須添加四個空格將其格式化爲一段代碼,然後爲可見的縮進添加*四個空格。不要使用標籤。 –

+0

謝謝!我無法弄清楚如何讓塊在寫多行時保持穩定。 – NateH06

回答

5

(這個例子是令人困惑的是Meeting真的Parent?)

getChild1List第一個版本,該collect(toList())方法被調用一個Stream<Child1>及其目標類型 - 由getChild1List返回類型確定 - 是List<Parent>。這是有效的,因爲它允許類型T的流由超類型T的收集器收集。更具體地說,您將類型Child1的實例添加到類型安全並且被允許的List<Parent>。您也可以將getChild1List()的聲明更改爲List<Child1>而不是List<Parent>

你能看到的變化是由Stream<T>望着collect()聲明允許:

<R,A> R collect(Collector<? super T,A,R> collector) 

? super T是允許的偏差。

你的returnsListByContact聲明,

<T extends Parent> List<T> returnsListByContact(List<T> childList, ...) 

允許偏差。它需要一個List<T>類型的參數並返回一個List<T>。參數和返回類型必須相同。這就是爲什麼當你傳遞一個List<Child1>並嘗試從一個返回類型爲List<Parent>的方法返回時 - 這些類型是不兼容的。

要解決這個問題,您需要在聲明returnsListByContact中添加一些差異。以下是我想做到這一點:

<T extends Parent> List<T> returnsListByContact(List<? extends T> childList, ...) 

這使您可以返回一些類型的列表,同時通過一些亞型的列表,在這種情況下返回List<Parent>而傳遞List<Child1>,這是我想你想。

+2

加上第一句,我也無法理解它。 – Eugene

+0

是的,Meeting是實際名稱 - 它的任何實例都是Parent。編輯我的原始代碼更清晰。以爲我已經清除了我的代碼,諷刺地使這個可讀的普通人羣......太多的時間在這個項目...... – NateH06

+0

有時間來處理這個,你的修復工作非常好。我以爲'.collect()'的返回類型是基於你輸入到'Stream'的內容,並且不知道該方法的返回類型對結果有任何影響。非常感謝! – NateH06