Как вставить & # 8220; Pair & # 8221; или n-размер в коллекцию списков вместо того, чтобы составлять HashMaps?

StackOverflow https://stackoverflow.com/questions/835359

Вопрос

Итак, у меня есть ситуация, когда мне нужно передать три значения в последовательную очередь BlockingQueue:

(SelectableChannel, ComponentSocketBasis, Integer).

На самом деле их вообще не нужно отображать в хэш, и использование HashMap нелепо, поскольку для каждой записи всегда будет только один ключ; было бы хорошо, если бы они были только в каком-то упорядоченном наборе. Однако из-за отсутствия известной альтернативы я использовал HashMap в своей реализации и произвел эту запутанную обобщенную композицию:

private LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>> deferredPollQueue = new LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>>();

Это кажется действительно смешным. Я должен быть ужасным n00b. Конечно, есть лучший способ сделать это, который не требует, чтобы я разлагал ключ при извлечении значений или тратил (теоретически - на практике, Java всегда раздутый :) алгоритмическая сложность на бесполезных хэш-вычислениях, которые мне не нужны потому что у меня есть пространство ключей 1 и я даже не хочу реляционно сопоставить три ссылки, а просто сгруппировать их? С этой реализацией я должен вытащить значения таким образом:

while(deferredPollQueue.size() > 0) {
    System.out.println("*** Draining new socket channel from queue");
    HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer> p = deferredPollQueue.take();

    SelectableChannel chan = null;
    ComponentSocketBasis sock = null;
    int ops = 0;

    HashMap<SelectableChannel, ComponentSocketBasis> q = p.keySet().iterator().next();

    chan = q.keySet().iterator().next();
    sock = q.get(chan);

    ops = p.get(q).intValue();

    SelectionKey k = chan.register(selector, ops);  

    if(!channelSupervisorMap.containsKey(k))
        channelSupervisorMap.put(k, sock);
}

Я почти уверен, что каждое существо, способное на разумную причину, вероятно, думает, что это нелепый способ сделать это, поэтому вопрос в том, какой правильный путь? :) Я нигде не могу найти доказательства java.util.Pair или java.util.Triplet.

Я полагаю, что православный путь (TM) должен был бы создать пользовательский класс или интерфейс только для того, чтобы вместить этот триплет, но для такой маленькой задачи в такой большой системе это кажется нелепо многословным и ненужным - хотя, опять же, это сама Java.

Точно так же, возможно, значения могут быть помещены в ArrayList или Vector или их производные, но в Java это не дает более краткого способа их решения, чем я выхожу из этого HashMap, хотя здесь это действительно решает проблему алгоритмической сложности, возможно.

Вернувшись на землю Perl, мы бы просто сделали это, используя ссылку на массив в качестве значения внутри массива:

push(@$big_queue_array, [$elem1, \%elem2, \@elem3]);

Какой лучший эквивалент в Java?

Это было полезно?

Решение

Почему бы просто не создать свои собственные классы Pair или Triple? Практически каждый проект Java 5+ заканчивается тем, что они имеют свои собственные классы утилит!

Другие советы

Вы говорите, что пользовательский класс для хранения триплета будет раздутым и ненужным, но на самом деле это способ сделать это, вот как работает объектно-ориентированное моделирование. Пользовательский класс является явным и читаемым и занимает не больше ресурсов времени выполнения, чем общий класс-держатель.

Функциональная Java имеет пары , триплеты и кортежи до arity 8. Существует также тип с именем HList для произвольной арности. Таким образом, ваш тип будет:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

Это просто библиотека, поэтому поместите банку в путь к классам, и все готово.

Вы можете просто использовать ArrayList для хранения объектов, поскольку вы знаете, какой объект будет в каком месте. Создание нового класса с членами SelectableChannel и ComponentSocketBasis для, вероятно, будет лучше.

Если вы собираетесь много заниматься такими вещами, создание общей пары или кортежа сейчас сэкономит вам много времени, но если это единственное место, где вы собираетесь его использовать, то создание нового класса значительно облегчит чтение кода.

Всякий раз, когда вы видите свое имя класса в коде, вы точно знаете, для чего оно предназначено, тогда как, если вы просто видите свое общее объединение, вам (или кому-то еще) будет сложнее понять, для чего оно используется. .

Это компромисс между временем программирования и удобочитаемостью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top