2009-05-07 7 views
0

Итак, у меня есть ситуации, когда мне нужно пройти в течение трех значений в последовательные очереди BlockingQueue:Как вставить «пар» или n-размер в коллекцию списков вместо составления HashMaps?

(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?

ответ

5

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

+0

Серьезно? Это считается кошерным? :) Прошу прощения, C и Perl парень здесь - просто пытаюсь понять вещи. –

+1

Да, общая пара является одним из примеров на http://en.wikipedia.org/wiki/Generics_in_Java, хотя они забыли переопределить равные и хэш-коды. – JeeBee

+0

Итак, в вашем коде у вас будет «частный LinkedBlockingQueue > foo;". Тем не менее, нет ничего плохого в создании конкретного класса с тремя членами и есть имена здравого метода, такие как «getSelectableChannel()» вместо «getFirst()», как у вас было бы с Pair/Triplet. – JeeBee

4

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

+0

Это то, что я подозревал, но не хотел этого делать. Извините, новичок здесь. Не хотел заканчивать на TheDailyWTF или что-то в этом роде. В связи с этим, как вы думаете, как вы думаете, я должен создать пользовательский класс триплетов специально для хранения этих значений в этой ситуации или сделать в качестве комментария выше, который вы предлагаете, и создать общий класс Pair и/или Triplet с ссылками на Object? –

+0

Я бы создал пользовательский класс по причинам, приведенным выше - читаемость - это король, мой друг. – skaffman

+0

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

2

Functional Java имеет pairs, triplets и кортежи до арности 8. Там также типа, называемый HList для арности произвольной. Так что ваш тип будет:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>> 

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

2

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^