2010-03-17 3 views
2

У меня есть Enum for Days of week (с Everyday, weekend и weekdays), как указано ниже, где каждая запись имеет значение int.Расчет недельных дней Java

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; 
    } 
} 

распределил любой комбинации значений, то, что было бы самым простым способом вычислить все индивидуальные значения и сделать ArrayList от него. Например, учитывая число 56 (т. Е. Wed + Thur + Fri), как рассчитать дни.

+1

Здесь вы не можете использовать 62, 65, 127. Вам нужны 1, 2, 4, 8, 16, 32, 64, 128, 256 и 512, чтобы заставить его работать «простым способом» (чего я еще не могу сказать с головы, но кто-то еще;)). – BalusC

+2

@BalusC: эти значения представляют собой предопределенные комбинации, не предназначенные для дальнейшего объединения. –

+0

В качестве альтернативы, если вы формируете «total» с использованием побитового OR ('|'), а не сложения ('+'), тогда могут быть созданы битовые комбо, например 65 или 127. –

ответ

4

Как предложил Майкл, не раскрывайте эту деталь реализации внешнему миру. Создать статический метод, который преобразует INT битовой маску 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; 
} 

Вы также можете понадобиться статический метод, который преобразует EnumSet в битовой маску, я оставляю это упражнение для читателя.

Кроме того, просмотр вашего перечисления, каждый день, выходные и будние дни там не принадлежат. Они представляют собой совокупности ваших других значений DaysOfWeek и как таковые должны быть определены как EnumSets.

+0

Excellant. оно работает. благодаря – Shahid

6

Правильный способ представления коллекции значений перечисления - использовать EnumSet. Это использует внутренний вектор бит. Но разоблачение такой детали реализации, как в вашем коде, не является хорошей идеей. Мы делаем OO здесь, а не бит-twiddling.

Кроме того, вы смешиваете понятия одного значения и набор значений, которые, вероятно, приведут к головным болям в будущем.

Пример использования перечисления DayOfWeek, встроенного в Java 8 и более поздних версий.

EnumSet<DayOfWeek> weekend = EnumSet.of(DayOfWeek.SATURDAY , DayOfWeek.SUNDAY); 

Boolean isTodayWeekend = weekend.contains(LocalDate.now().getDayOfWeek()); 
+0

Спасибо. если я удаляю Everyday, выходные и будни из Enum и использую Enumset вместо этого, как бы я вычислил дни из данной суммы. – Shahid

+1

@Shahid: Вы полностью прекратите использовать int «total» и вместо этого будете использовать EnumSet везде. Everyday, Wekkdays и Weekend будут публичными статическими окончательными экземплярами EnumSet, завернутыми в немодифицируемые. Затем вы можете скопировать их и добавить() и удалить() дни или использовать EnumSet.of() для создания других комбинаций. –

+0

Может возникнуть необходимость в сериализации битового набора и передачи его в приложения, отличные от Java, для этого может потребоваться преобразование из бит в EnumSet и наоборот. Если перечисление предназначено только для использования на Java, то я согласен с вами, бит абсолютно не нужен. –