2016-12-06 46 views
3

我怎樣才能做到以下(不編譯):Java過濾器列表中的通用類型T

<T> List<T> getElementsOf() { 
    return list.stream() 
      .filter(x -> x instanceof T) 
      .map(x -> (T) x) 
      .collect(toList()); 
} 

什麼是例如使用的?理想情況下,它應該像obj.<Derived>getElementsOf()

+0

請問您是否對您的需求,需求,問題有更具體的瞭解... – AxelH

+0

什麼是'list'類型是否是'object' - 如果是這種情況'instanceof'不會工作 –

+0

您可能是對Guava的['Iterables.filter()']感興趣(https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/Iterables.html#filter-java.lang .Iterable-java.lang.Class-)。請注意第一個等價物,它與@ Sweeper的解決方案相同。 – shmosel

回答

8

雖然對方的回答幾乎做工作,這裏有一個更好的:

<T> List<T> getElementsOf(Class<T> clazz) { 
    return list.stream() 
      .filter(clazz::isInstance) 
      .map(clazz::cast) 
      .collect(toList()); 
} 

注意,clazz::isInstance啄。它不是比較兩個類,而是使用isInstance方法。根據文檔,這相當於instanceof,這是你想要擺在首位。

該方法是Java語言instanceof操作符的動態等價物。

+1

我想你也可以'映射(clazz :: cast)'而不是'map(x - >(T)x)'。 – lexicore

+0

@lexicore哦,我沒有注意到!現在編輯! – Sweeper

1

我有以下幾點:

<T> List<T> getChildrenOf(Class<T> clazz) { 
    return children.stream() 
      .filter(node -> node.getClass() == clazz) 
      .map(node -> clazz.<T>cast(node)) 
      .collect(toList()); 
} 

List<Mesh> nameNodes = b.getChildrenOf(Mesh.class); 
0

注意泛型類型信息在運行時被刪除,所以要做出更清楚我Object交換T。其實Object不會有太多,但我一直是使其更清晰,其中T是:

List<Object> getElementsOf() { 
    return list.stream() 
     .filter(x -> x instanceof Object) // this is legal, as Object is an actual type, T isn't 
     .map(x -> (Object) x) 
     .collect(toList()); 
} 

正如你可以看到現在,這並沒有太大的意義。如果不將它作爲參數傳遞,則無法推斷該類型。你自己已經得到了解決方案,我只想讓其他對泛型不熟悉的人也更清楚。

<T> List<T> getElementsOf(Class<T> type) { 
    return list.stream() 
       .filter(type::isInstance) 
       .map(type::cast) 
       .collect(toList()); 
} 

如果我們使用對象現在交換T,我們將看到,該類型是還在這裏,所以你可以適當地投它:

List getElementsOf(Class type) { 
    return list.stream() 
       .filter(type::isInstance) // is type an Object? is it Long? we don't mind... we passed it and we deliver it 
       .map(type::cast) // actually this isn't really needed, if you have a return type of List (as you already filtered for the types you want) 
       .collect(toList()); 
} 

還要注意,用這種方法你永遠不會提供類型時獲取null值。在這種情況下,isInstance將返回false