如何在方法中流式传输Java List(Varargs)的值?

时间:2019-05-12 16:17:23

标签: java list java-8 java-stream

我有以下方法:

public static List<A> getValuesExclusion(A exclusion) {
        return Arrays.stream(values())
                .filter(item -> item != exclusion)
                .collect(Collectors.toList());
}
//this function returns enum list of A types that has no A type'exclusion'

现在,我想将其作为参数添加到列表中:

public static List<A> getValuesExclusion(A... exclusions){
        return Arrays.stream(values())
                .filter(???)
                .collect(Collectors.toList());
}

我的问题是,如何为第二种情况做过滤器?我想检索一个将所有值“ exclusions”排除在外的枚举列表。这是类A的属性:

public enum A implements multilingualA{
    A("a"),
    B("b"),
    C("c"),
    D("d");
    ...
}

3 个答案:

答案 0 :(得分:5)

如果要确保exclusions中未包含所有项目,可以执行以下操作:

public static List<A> getValuesExclusion(AType... exclusions){
        return Arrays.stream(values())
                .filter(e -> Arrays.stream(exclusions).noneMatch(c -> c == e))
                .collect(Collectors.toList());
}

这将在Stream中创建一个exclusions,然后使用noneMatch()确保给定的AType不包含在Array

答案 1 :(得分:3)

对于包含唯一元素的内容,您应该重新考虑List是否真的是合适的数据类型。通常使用Set更合适。

然后,如果您关心性能,则可以将其实现为

public static Set<A> getValuesExclusion(A... exclusions){
    return exclusions.length == 0? EnumSet.allOf(A.class):
        EnumSet.complementOf(EnumSet.of(exclusions[0], exclusions));
}

EnumSet是专为容纳enum类型的元素而设计的,只为每个常量存储一个位,以告知其存在或不存在。这样就可以使用complementOf之类的操作,它只需使用一次“二进制非”操作就可以翻转所有位,而无需实际遍历enum常量。

如果您坚持要返回List,则可以轻松完成

public static List<A> getValuesExclusion(A... exclusions){
    return new ArrayList<>(exclusions.length == 0? EnumSet.allOf(A.class):
        EnumSet.complementOf(EnumSet.of(exclusions[0], exclusions)));
}

答案 2 :(得分:2)

我不会在这里使用Stream,而是使用一种更具可读性的方法:

public static List<A> getValuesExclusion(AType... exclusions){
    List<A> values = Arrays.asList(values());
    values.removeAll(Arrays.asList(ex));
    return values;
}