[英]Java > Filter a Generic Collection
Basically, I'd like to use a Predicate
to filter a generic (which extends Collection), and then return an instance of the same generic Collection implementation (preferably a new instance) eg implement the method signature F removeNulls(F inputs)
. 基本上,我想使用Predicate
来过滤泛型(扩展Collection),然后返回相同的泛型Collection实现的实例(最好是新实例),例如,实现方法签名F removeNulls(F inputs)
。
I have the following examples, but there are caveats to each ( removeNulls4
is probably the closest to what I'm trying to achieve): 我有以下示例,但是每个示例都有一些警告( removeNulls4
可能是我想要达到的最接近的示例):
F
(requires casting) 返回的列表可能不是F
的实例(需要强制转换) F
may not have an empty constructor F
的实现可能没有空的构造函数 forReturn
object is not thread safe (if run in parallel) 使用forReturn
对象不是线程安全的(如果并行运行) filter
method) 正在重新设计轮子/不可平行(希望使用filter
方法) Iterator.remove()
can throw an UnsupportedOperationException
Iterator.remove()
可以引发UnsupportedOperationException
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class QuickTest<I, F extends Collection<I>> {
Predicate<I> removeNullsPredicate = x -> x != null;
@SuppressWarnings("unchecked")
public F removeNulls1(F inputs) throws Exception {
return (F) inputs.stream().filter(removeNullsPredicate)
.collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
public F removeNulls2(F inputs) throws Exception {
F forReturn = (F) inputs.getClass().newInstance();
inputs.stream().filter(removeNullsPredicate)
.collect(Collectors.toCollection(() -> forReturn));
return forReturn;
}
public F removeNulls3(F inputs) throws Exception {
Iterator<I> iter = inputs.iterator();
while (iter.hasNext()){
I next = iter.next();
boolean test = removeNullsPredicate.test(next);
if (!test){
iter.remove();
}
}
return inputs;
}
public F removeNulls4(F inputs) throws Exception {
List<I> forRemoval = inputs.stream().filter(removeNullsPredicate.negate())
.collect(Collectors.toList());
inputs.removeAll(forRemoval);
return inputs;
}
}
You could provide a Supplier<F>
as an argument: 您可以提供Supplier<F>
作为参数:
public F removeNulls(F inputs, Supplier<F> factory) {
return inputs.stream().filter(removeNullsPredicate)
.collect(Collectors.toCollection(factory));
}
Then simply call: 然后只需调用:
List<I> nonNulls = removeNulls(inputs, ArrayList::new);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.