Java8Lambdas——类型c#的等价物
我现在正在学习新的Java8特性,在C#world中只呆了4年,所以Lambda是我的首选。我现在正努力为C#的“OfType”方法找到一个等价物 我有一个列表myNodes,我想从中得到一个列表,其中Node是一个接口,SpecificNode正在实现它 在C#中,应该是Java8Lambdas——类型c#的等价物,java,c#,java-8,lambda,Java,C#,Java 8,Lambda,我现在正在学习新的Java8特性,在C#world中只呆了4年,所以Lambda是我的首选。我现在正努力为C#的“OfType”方法找到一个等价物 我有一个列表myNodes,我想从中得到一个列表,其中Node是一个接口,SpecificNode正在实现它 在C#中,应该是 IList<INode> myNodes = new List<INodes>(){new SpecificNode(), new OtherNode()} IList<SpecificNode
IList<INode> myNodes = new List<INodes>(){new SpecificNode(), new OtherNode()}
IList<SpecificNode> specificNodes = myNodes.OfType<SpecificNode>()
IList myNodes=new List(){new SpecificNode(),new OtherNode()}
IList specificNodes=myNodes.OfType()的
Java中的.OfType()
方法与没有精确的匹配,但是您可以使用Java8的过滤功能:
IList<INode> myNodes = new ArrayList<INode>();
myNodes.add(new SpecificNode());
myNodes.add(new OtherNode());
List<SpecificNode> filteredList = myNodes.stream()
.filter(x -> x instanceof SpecificNode)
.map(n -> (SpecificNode) n)
.collect(Collectors.toList());
IList myNodes=new ArrayList();
添加(新的SpecificNode());
添加(新的OtherNode());
List filteredList=myNodes.stream()
.filter(x->x SpecificNode实例)
.map(n->(SpecificNode)n)
.collect(Collectors.toList());
如果要获得显式强制转换,可以执行以下操作:
List<SpecificNode> filteredList = myNodes.stream()
.filter(SpecificNode.class::isInstance)
.map(SpecificNode.class::cast)
.collect(Collectors.toList());
List filteredList=myNodes.stream()
.filter(SpecificNode.class::isInstance)
.map(SpecificNode.class::cast)
.collect(Collectors.toList());
您可以创建一个包含流管道的函数,从而减少其调用
Function<List<INode>,List<SpecificNode>> ofSub =
bl -> bl.stream()
.filter(x -> x instanceof SpecificNode)
.map(n -> (SpecificNode) n)
.collect(Collectors.toList());
我也有同样的问题。这就是我想到的,但是由于java不做扩展方法(可能在10年后?),所以它是一种静态方法。这是在使用流API,尽管没有特定的原因必须这样做。同样的基本检查在带有预分配ArrayList的
for
循环中也可以正常工作
@SuppressWarnings("unchecked")
private static <T> List<T> ofType(Class<?> out, List<Object> 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<Object> objlist = list("ABC", 3, "def", -30.39);
puts("strings=", ofType(String.class, objlist)); // strings= [ABC, def]
puts("integers=", ofType(Integer.class, objlist)); // integers= [3]
@SuppressWarnings(“未选中”)
类型的私有静态列表(类输出,列表){
return list.stream().filter(x->out.isAssignableFrom(x.getClass()))
.map(x->(T)x)//未选中
.collect(Collectors.toList());
}
//仅供参考,此代码使用“boon”库
列表对象列表=列表(“ABC”,3,“def”,-30.39);
puts(“strings=”,of type(String.class,objlist));//字符串=[ABC,def]
puts(“integers=”,of type(Integer.class,objlist));//整数=[3]
这是一个不使用流的版本。它的工作原理是一样的,但流的一些乐趣是。。。如果你喜欢的话,你也许可以将它们流式传输。除了像这样的帮手,我不觉得它很有用
private static <T> List<T> ofType(Class<?> out, List<Object> list) {
List<T> outList = new ArrayList<T>(list.size());
for(Object o : list) {
if ( out.isAssignableFrom(o.getClass())) {
outList.add((T)o);
}
}
return outList;
}
类型的私有静态列表(类输出,列表){
List outList=newarraylist(List.size());
用于(对象o:列表){
if(out.isAssignableFrom(o.getClass())){
大纲图。添加((T)o);
}
}
返回最长时间;
}
不必先过滤流,然后将其映射到所需的目标类型,可以通过flatMap
对流进行一次调用,也可以使用此小辅助函数:
private static <Target extends Base, Base> Function<Base, Stream<Target>> ofType(Class<Target> targetType) {
return value -> targetType.isInstance(value) ? Stream.of(targetType.cast(value)) : Stream.empty();
}
在flatMap
操作的帮助下,所有返回的流都可以连接起来
我认为单独的检查和强制转换更容易理解,执行起来可能更快,这只是一个单流操作的概念证明。您只需要在过滤器和收集器之间有一个
.map(n->(SpecificNode)n)
。谢谢!即使整个构造比C#长得多,它也能工作,这真是一个遗憾;(@PetrOsipov,我几乎可以肯定它可以缩短。我会进一步研究。)肯定是一个选择。java中是否有c#的扩展方法的等价物?如果存在的话,使用它们可能更容易…尝试在语言Y中找到语言X的特征f通常不是最好的方法。除此之外,每种语言都提供(或多或少)正交函数集。试图塞满所有东西的语言都有超重的问题。@PetrOsipov:Java花了数年时间才赶上lambdas上的C#语言——如果有扩展方法的话,还需要数年时间。Java不能像C#那样快速扩展。这是最好的答案。不明白为什么它被低估了
private static <Target extends Base, Base> Function<Base, Stream<Target>> ofType(Class<Target> targetType) {
return value -> targetType.isInstance(value) ? Stream.of(targetType.cast(value)) : Stream.empty();
}
Stream.of(1, 2, 3, "Hallo", 4, 5, "Welt")
.flatMap(ofType(String.class))
.forEach(System.out::println);