Страницы

Поиск по вопросам

среда, 19 декабря 2018 г.

Можно ли написать “абстрактный” enum?

Есть такой enum:
public enum AlbumPrivacy {
public_(0), friendsOnly(1), familyOnly(2), friendsAndFamily(3), private_(4);
private final int _value; private static AlbumPrivacy[] _values;
private AlbumPrivacy(int value) { _value = value; }
public int getValue() { return _value; }
public static AlbumPrivacy fromInt(int i) { if (_values == null) _values = AlbumPrivacy.values();
for (AlbumPrivacy b : _values) { if (b.getValue() == i) { return b; } } return null; } }
Зачем такое нагородил? Удобно, когда пишешь в базу - быстро сохранять в int и назад.
Но очень не удобно для каждого нового enum писать копию кода. А извернуться и убрать эту дубликацию кода нельзя?
И второй вопрос - правильно ли я сделал, что храню список values, а не каждый раз дёргаю при вызове fromInt?
UPD:
Может тогда вот так сделать:
public class EnumUtils {
private static Map, Object[]> _enums;
@SuppressWarnings("unchecked") public static > T fromInt(Class clazz, int index) { if (_enums == null) _enums = U2.map();
Object[] values = _enums.get(clazz);
if (values == null) { Enum[] _values = clazz.getEnumConstants(); values = new Object[_values.length];
for (int i = 0; i < _values.length; i++) values[i] = _values[i];
_enums.put(clazz, values); }
return (T) values[index]; } }
А enum объявлять по простому, без всяких номеров.
UPD2:
public static > T fromInt(Class clazz, int index) { return clazz.getEnumConstants()[index]; }


Ответ

У каждого enum и так есть порядковое значение поля — метод ordinal(). Если у вас все value идут по порядку, посто делайте
public enum AlbumPrivacy { public_, // 0 friendsOnly, // 1 familyOnly, // 2 friendsAndFamily, // 3 private_; // 4 }
Для определения номера по enum:
int n = AlbumPrivacy.friendsOnly.ordinal();
Для определения enum по номеру:
AlbumPrivacy value = AlbumPrivacy.values()[3];
Если вас это не устраивает (скажем, номера могут идти с дырками), можно во-первых, реализовать интерфейс, а во-вторых сделать метод fromInt универсальным.
interface Ordinal { int getValue(); }
public enum AlbumPrivacy implements Ordinal {
public_(0), friendsOnly(1), familyOnly(2), friendsAndFamily(3), private_(4);
private final int _value;
private AlbumPrivacy(int value) { _value = value; }
@Override public int getValue() { return _value; } }
// Где-нибудь в утилитном классе: public static & Ordinal> T fromInt(Class clazz, int i) { T[] values = clazz.getEnumConstants(); for(T value : values) { if(value.getValue() == i) return value; } throw new IllegalArgumentException(); }

Комментариев нет:

Отправить комментарий