Сопоставление между перечислением и строкой?

Итак, недавно я прочитал этот пост и хочу эффективно то же самое.

Мне было все равно на «уродство» и т. д., поэтому я реализовал один из методов следующим образом:

public enum Day {

    Monday(1), 
    Tuesday(2), 
    Wednesday(3), 
    Thursday(4), 
    Friday(5), 
    Saturday(6), 
    Sunday(7);

    public final int id;

    Day(int id) {
        this.id = id;
    }

    public static Day getByID(int id) {
        Day d = null;
        for (Day dTemp : Day.values())
        {
            if (id == dTemp)
            {
                d = dTemp;
                break;
            }
        }

        return d;
    }

    public Day getNext() {
        return values()[(ordinal()+1)%values().length];
    }

    public Day getPrev() {
        return values()[(ordinal()-1)%values().length];
    }
}

Но проблема с ним заключается в операторе if, когда я делаю:

if (id == dTemp)

Пишет, что это несовместимые типы. Что мне делать, чтобы это исправить?


person Bhaxy    schedule 02.01.2012    source источник
comment
Вас ввел в заблуждение С#, дитя мое? (msdn.microsoft.com/en-us/library/cc138362.aspx)   -  person The Nail    schedule 03.01.2012


Ответы (2)


Используйте 1_. Перечисления - это классы, а значения перечисления - это объекты, а не целые числа, и поэтому их нельзя привести (ни явно, ни неявно) к int.

В качестве альтернативы обратите внимание, что перечисления имеют порядковый номер, то есть идентификатор их позиции. В вашем примере Monday будет иметь порядковый номер 0, а Sunday будет иметь порядковый номер 6. Вы получаете доступ к порядковому номеру, вызывая метод ordinal().

Таким образом, если id основано на единице, вместо этого вы можете сделать следующее:

public static Day getByID(int id) {   
  //check id is between 1 and 7, I'll leave that for you
  return Day.values()[id - 1];
}

Обратите внимание, что вы можете захотеть кэшировать Day.values() в частной статической переменной и затем обращаться к этому кэшированному массиву.

Кстати, где строка, которую вы упоминаете в своем вопросе?

person Thomas    schedule 02.01.2012
comment
К вашему сведению, Bhaxy уже использует ordinal()s для получения следующего и предыдущего дня. - person The Nail; 03.01.2012
comment
@TheNail да, я тоже это видел. Интересно, почему он не использует его в этом статическом методе. - person Thomas; 03.01.2012

if(id == dTemp.id)

Должно сработать.


В качестве альтернативы попробуйте метод ordinal() из enum.

public final int ordinal() Возвращает порядковый номер этой константы перечисления (ее позицию в объявлении перечисления, где исходной константе присваивается порядковый номер нуля). Большинству программистов этот метод не пригодится. Он предназначен для использования сложными структурами данных на основе перечисления, такими как EnumSet и EnumMap.

Возвращает: порядковый номер этой константы перечисления. см..


Ну, я скопировал ваш код и соответственно протестировал.

Оба

if (id == dTemp.ordinal()+1)

и

if(id == dTemp.id)

работал нормально и производил, как ожидалось. Заявление

System.out.println(Day.Friday.getByID(1));

выдает понедельник.

person Lion    schedule 02.01.2012