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