简体   繁体   English

Java>过滤通用集合

[英]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可能是我想要达到的最接近的示例):

Caveats 注意事项

removeNulls1: removeNulls1:

  • the returned list may(/will) not be an instance of F (requires casting) 返回的列表可能不是F的实例(需要强制转换)

removeNulls2: removeNulls2:

removeNulls3: removeNulls3:

removeNulls4: removeNulls4:

  • modifies the original list 修改原始清单
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM