tags:

views:

218

answers:

2

I have an Enum for Days of week (with Everyday, weekend and weekdays) as follows where each entry has an int value.

public enum DaysOfWeek {


  Everyday(127),
  Weekend(65),
  Weekdays(62), 
  Monday(2),
  Tuesday(4),
  Wednesday(8),
  Thursday(16),
  Friday(32), 
  Saturday(64),
  Sunday(1);

  private int bitValue;

  private DaysOfWeek(int n){
    this.bitValue = n;
  }

  public int getBitValue(){
    return this.bitValue;
  }
}

Given a TOTAL of any combination of the values, what would be the simplest way to calculate all individual values and make an arraylist from it. For example given the number 56 (i.e. Wed+Thur+Fri), how to calculate the days.

+5  A: 

The correct way to represent a collection of enum values is to use an EnumSet. This uses a bit vector internally. But exposing such an implementation detail as in your code is not a good idea. We're doing OO here, not bit-twiddling. Additionally, you are mixing the concepts of a single value and a collection of values, which will likely lead to headaches down the road.

Michael Borgwardt
Thanks. if I remove Everyday, weekend and weekdays from the Enum and use Enumset instead how would I calculate the days from a given total.
Shahid
@Shahid: You'd stop using int "total" completely and instead use an EnumSet everywhere. Everyday, Wekkdays and Weekend would be public static final EnumSet instances wrapped to be unmodifiable. Then you can copy these and add() and remove() days or use EnumSet.of() to build other combinations.
Michael Borgwardt
@Michael. There may be a need to serialize a bitset and pass it off to non-Java applications, for this it may be necessary to convert from bits to EnumSet and vice versa. If the enum is only intended to be used in Java, then I agree with you, the bits are totally unnecessary.
Alexander Pogrebnyak
thanks Michael.
Shahid
+2  A: 

As Michael suggested do not expose this implementation detail to the outside world. Create a static method that converts int bitmask to EnumSet:

public static EnumSet< DaysOfWeek > fromBitValues (
        final int origBitMask
    )
{
    final EnumSet< DaysOfWeek > ret_val =
        EnumSet.noneOf( DaysOfWeek.class );

    int bitMask = origBitMask;

    for ( final DaysOfWeek val : DaysOfWeek.values( ) )
    {
        if ( ( val.bitValue & bitMask ) == val.bitValue )
        {
            bitMask &= ~val.bitValue;

            ret_val.add( val );
        }
    }

    if ( bitMask != 0 )
    {
        throw
            new IllegalArgumentException(
                String.format(
                    "Bit mask value 0x%X(%d) has unsupported bits " +
                    "0x%X.  Extracted values: %s",
                    origBitMask,
                    origBitMask,
                    bitMask,
                    ret_val
                )
            );
    }

    return ret_val;
}

You may also need a static method that converts an EnumSet to a bit mask, I leave this exercise to the reader.

Also, looking at your enum, Everyday, Weekends and Weekdays do not belong there. They are aggregates of you other DaysOfWeek values and as such should be defined as EnumSets.

Alexander Pogrebnyak
Excellant. it works. thanks
Shahid