Java: использование перечисления в качестве ссылки на массив - PullRequest
5 голосов
/ 23 февраля 2012

Я хотел бы сослаться на массив с типом enum.Это довольно стандартная вещь в C ++ (мой источник), однако я не уверен, возможно ли это / желательно в Java.

Например, я хотел бы иметь перечисление, такое как:

public enum Resource {
    COAL,
    IRON
}

Затем позже я хотел бы сослаться так:

Amount[COAL] // The amount of coal
Price[IRON]  // The price of iron

Я не хочу создавать Amount и Price полей Resource, как я хотел бы получить списокобъекты (заказы на ресурсы), сгруппированные по типу ресурса.Назначение int для каждого типа Resource вручную не лучше, чем public static int final BLAH Я чувствую, ничего не получилось.

По сути, я ищу перечисление C ++, которое маркирует вещи.Я понимаю, что это может быть «неправильным» способом ведения дел в Java, поэтому не стесняйтесь указывать мне направление правильного духа Java.

Ответы [ 6 ]

13 голосов
/ 23 февраля 2012

В C ++ перечисление фактически является псевдонимом для целого числа.В Java это «правильные» объекты, поэтому вы не можете использовать их в качестве ссылки на массив.

Если вы хотите посмотреть значение в вашем массиве, которое связано с конкретным объектом перечисленияэто звучит как карта для меня!Как насчет замены этих массивов на EnumMap<Resource, Double>?

Класс EnumMap оптимизирован для использования с ключами enum, так что он в конечном итоге использует массив, присвоенный порядковому порядку перечислений (integer) значение за кадром.Так что это намного быстрее, чем хэш-карта общего назначения, и вы получаете скорость решения на основе массива с семантической выразительностью Map - это лучшее из обоих миров.

1 голос
/ 23 февраля 2012

Каждый элемент перечисления Java имеет порядковый номер, связанный с ним, проиндексированный с нуля в соответствии с порядком определения в перечислении.Просто используйте, например,

COAL.ordinal()

Однако мне кажется, что вам лучше создать класс, например, Order с полями для Amount и Price, а затем сохранить набор из них, например, на карте, проиндексированнойenum элементы.

например

Map<Resource, Order> orders = new HashMap<Resource, Order>();
orders.put(Resource.COAL, new Order(price, amount));
1 голос
/ 23 февраля 2012

Вы можете сделать почти это. В отличие от C ++, где enum является просто int, Java enum является классом. Таким образом, вы не можете использовать его в качестве индекса массива. Но у каждого элемента перечисления есть ordinal(), что является целым числом, так что вы можете сказать

amount[COAL.ordinal()]
price[IRON.ordinal()]

Но у вас есть лучший подход. Можно добавить методы в enum, чтобы он выглядел так:

IRON.price(amounts)
COAL.amount(prices)

Я думаю, что этот подход намного лучше.

0 голосов
/ 23 февраля 2012

Карты очень хороши для более динамичных данных. Но вы также должны кодировать всю проверку на двойные имена, двойные значения, существующие имена / значения и все прочее. И даже в этом случае, если вы сделаете ошибку, она будет обнаружена только во время выполнения.

Для более статических данных лучше использовать не примитивные перечисления, а перечисления нового типа из Java 6 . Они превосходны! И ошибки будут найдены компилятором.

public enum Resource{
    COAL(0), IRON(1);
    int index;
    private Resource(int index){
        this.index=index;
    }
}
...
amount[Resource.COAL.index]=...

Но лучше вариант:

public enum Resource{
    COAL(538,0.5f), IRON(115,1.5f);
    int amount;
    float price;
    private Resource(int amount, float price ){
        this.amount=amount;
        this.price=price;
    }
}
...
Resource.COAL.amount=...

Вы можете использовать их имя.

Вы можете сделать цикл через все перечисление:

for(Resource resourceType: Resource.values()) { 
   String toOutput=resourceType.name()+" amount="+ resourceType.amount;
}
0 голосов
/ 23 февраля 2012

Я думаю, что вы ищете EnumMap, http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumMap.html

Это не совсем массив, но так как ключ является перечислением, он все еще экономит место.

Это заканчивается как:

amount.get (Resource.COAL)

0 голосов
/ 23 февраля 2012

К сожалению, вам понадобится немного более длинный синтаксис:

Amount[COAL.ordinal()] // The amount of coal
Price[IRON.ordinal()]  // The price of iron

Если вам это не нравится, константы могут быть единственным вариантом, т. Е.

public class Resource {
    public static final int COAL = 0;
    public static final int IRON = 1;

}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...