Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stream value of Java List (Varargs) in a method?

I have the following method:

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'

Now I want to make it into a list as argument:

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

My question is, how can I do the filter for the second case? I would like to retrieve an enum list that excludes all the values "exclusions" as input. Here are the attributes of class A:

public enum A implements multilingualA{
    A("a"),
    B("b"),
    C("c"),
    D("d");
    ...
}
like image 366
Jack Avatar asked May 12 '19 16:05

Jack


2 Answers

If you want to make sure all the items are not included in the exclusions you could do:

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

Which will create a Stream of exclusions and then use noneMatch() to ensure the given AType is not included in the Array

like image 118
GBlodgett Avatar answered Oct 21 '22 05:10

GBlodgett


You should rethink whether List really is the appropriate data type for something containing unique elements. A Set usually is more appropriate.

Then, if you care for performance, you may implement it as

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

The class EnumSet is specifically designed for holding elements of an enum type, just storing a bit for each constant, to tell whether it is present or absent. This allows operations like complementOf, which just flips all bits using a single ⟨binary not⟩ operation, without the need to actually traverse the enum constants.

If you insist on returning a List, you can do it as easy as

public static List<A> getValuesExclusion(A... exclusions){
    return new ArrayList<>(exclusions.length == 0? EnumSet.allOf(A.class):
        EnumSet.complementOf(EnumSet.of(exclusions[0], exclusions)));
}
like image 44
Holger Avatar answered Oct 21 '22 05:10

Holger