12

I have an enum with 4 values, and I have a method signature that accepts an enum value. I would like to be able to do something with all enum values not passed as the argument to doSomething().

public void doSomething(EnumThing thing){
   EnumThing[] thingValues = EnumThing.values();
   List<EnumThing> valuesNotPassedAsArg = new ArrayList<EnumThing>();
   for(EnumThing th : thingValues){
       valuesNotPassedAsArg.add(th);
   }
   valuesNotPassAsArg.remove(thing);
  //here I would loop through all valuesNotPassAsArg and do something with them
}

public enum EnumThing{
 SOMETHING, SOMETHINGELSE, ANOTHERTHING;
}

Is there a cleaner way to do this? I feel as if the loop to get the items from the thingValues array is superfluous.

4
  • 1
    EnumThing.values(); will return all the enum values, and not any kind of subset. So, what exactly do you want to do? Please explain a little bit more. Commented Jan 8, 2013 at 21:10
  • from all enum values I am removing the enum value passed as the argument, and then I would like to loop through the remaining values. Commented Jan 8, 2013 at 21:11
  • And I thought you already knew how to loop through an Array, or Collection. Commented Jan 8, 2013 at 21:13
  • So you want the list of the enums excluding thing? Commented Jan 8, 2013 at 21:13

6 Answers 6

29

Look into EnumSet. Specifically,

import java.util.EnumSet;
import static java.util.EnumSet.complementOf;

for (EnumThing t : complementOf(EnumSet.of(thing))) {
  ... do the work ...
}
Sign up to request clarification or add additional context in comments.

Comments

4

@Marko's answer is better than this, but it might be helpful to know of this alternative way.

public static void main(String[] args) {
    EnumThing thing = EnumThing.ANOTHERTHING;

    List<EnumThing> list = new ArrayList<EnumThing>(Arrays.asList(EnumThing.values()));
    list.remove(thing);
    System.out.println(list);
}



public enum EnumThing{
    SOMETHING, SOMETHINGELSE, ANOTHERTHING;
}

This prints out

[SOMETHING, SOMETHINGELSE]

Comments

2

Another way is to use Stream.of method. For example:

public class EnumTest {

    public static enum MyEnum {
        VALUE1, VALUE2, VALUE3
    }

    public static void main(String[] args) {
        Stream.of(MyEnum.values()).filter(v -> v != MyEnum.VALUE2).forEach(System.out::println);
    }
}

Which prints:

VALUE1
VALUE3

Comments

1

Looking at your title, to iterate a range you do

for (int i = YourEnum.___RANGE___START___.ordinal() +1; i != YourEnum.__RANGE___END___.ordinal() ; i++) {
    YourEnumvalue = YourEnum.values()[i];
    //use value
}

or this

for (YourEnum value: EnumSet.range(YourEnum.___RANGE___START___, YourEnum.__RANGE___END___)) {
    // use value
}

I you just want to skip a single element, then Skip Head's solution might outperform the complementOf, which seems to be an overkill in case of single iteration.

Comments

0
public void doSomething(EnumThing thing){
   EnumThing[] thingValues = EnumThing.values();
   for(EnumThing th : thingValues){
       if (th != thing) {
          doSomethingElse(th);
       }
   }
}

Comments

0

Something like this is a little bit better I'd say

public void doSomething(EnumThing thing){
   EnumThing[] thingValues = EnumThing.values();
   List<EnumThing> valuesNotPassedAsArg = Arrays.asList(thingValues);
   valuesNotPassAsArg.remove(thing);
   //here I would loop through all valuesNotPassAsArg and do something with them
}
public enum EnumThing{
   SOMETHING, SOMETHINGELSE, ANOTHERTHING;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.