2016-12-06 54 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

相关问题