Java 8 Lambdas – 相当于c#OfType

我现在正在学习新的Java 8function,经过4年专门在C#世界,所以lambdas对我来说是最重要的。 我现在正在努力找到C#的“OfType”方法的等价物。

我所拥有的是List myNodes,我想从中获取一个List,其中Node是一个接口,而SpecificNode正在实现它。

在C#中它会是

IList myNodes = new List(){new SpecificNode(), new OtherNode()} IList specificNodes = myNodes.OfType() 

Java中没有.OfType()方法完全匹配,但您可以使用Java8的过滤function:

 IList myNodes = new ArrayList(); myNodes.add(new SpecificNode()); myNodes.add(new OtherNode()); List filteredList = myNodes.stream() .filter(x -> x instanceof SpecificNode) .map(n -> (SpecificNode) n) .collect(Collectors.toList()); 

如果你想得到明确的演员表,你可以这样做:

 List filteredList = myNodes.stream() .filter(SpecificNode.class::isInstance) .map(SpecificNode.class::cast) .collect(Collectors.toList()); 

我遇到了同样的问题。 这就是我想出来的,但是由于java不做扩展方法(可能再多10年?),它是一个静态方法。 这是使用流API,但没有特别的原因你必须这样做。 相同的基本检查在带有预分配ArrayList的for循环中可以正常工作。

 @SuppressWarnings("unchecked") private static  List ofType(Class out, List list) { return list.stream().filter(x -> out.isAssignableFrom(x.getClass())) .map(x -> (T) x) // unchecked .collect(Collectors.toList()); } // fyi this code uses "boon" library List objlist = list("ABC", 3, "def", -30.39); puts("strings=", ofType(String.class, objlist)); // strings= [ABC, def] puts("integers=", ofType(Integer.class, objlist)); // integers= [3] 

这是不使用流的版本。 它的工作原理是一样的,但是流的一些乐趣是……你可能能够流式传输它们,如果这是你的事情。 除了像这样的帮手之外,我并不经常发现它很有用。

 private static  List ofType(Class out, List list) { List outList = new ArrayList(list.size()); for(Object o : list) { if ( out.isAssignableFrom(o.getClass())) { outList.add((T)o); } } return outList; } 

您可以创建一个包含Stream管道的Function,从而减少其调用。

  Function,List> ofSub = bl -> bl.stream() .filter(x -> x instanceof SpecificNode) .map(n -> (SpecificNode) n) .collect(Collectors.toList()); 

例如:

  for( SpecificNode s: ofSub.apply( myNodes ) ){ //... } 

不是先过滤然后将流映射到所需的目标类型,而是可以通过flatMap对这个流进行单次调用以及这个小帮助函数:

 private static  Function> ofType(Class targetType) { return value -> targetType.isInstance(value) ? Stream.of(targetType.cast(value)) : Stream.empty(); } 

如果可以进行强制转换,则此Function基本上检查元素,然后对其进行强制转换,返回具有单个转换元素的流或如果无法转换则返回空流。

 Stream.of(1, 2, 3, "Hallo", 4, 5, "Welt") .flatMap(ofType(String.class)) .forEach(System.out::println); 

flatMap操作的帮助下,所有返回的流都可以连接在一起。

我假设分离的检查和转换更容易理解,甚至可能更快执行,这只是单个流操作的概念certificate。