Pergunta

Então, eu tenho uma situação onde eu preciso passar em três valores em uma fila BlockingQueue série:

(SelectableChannel, ComponentSocketBasis, Integer).

Eles não realmente precisa ser de hash mapeados em tudo, e usar um HashMap é ridículo como sempre haverá apenas uma chave para cada entrada; que seria bom se eles eram apenas em algum tipo de conjunto ordenado. Por falta de uma alternativa conhecido, no entanto, eu usei um HashMap em minha implementação e produziu este genéricos composição ofuscado:

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

Isto parece realmente ridículo. Eu devo ser um terrível n00b. Certamente há uma maneira melhor de fazer isso que não requer me para decompor a chave ao recuperar os valores ou perder o (teórico - na prática, a complexidade sempre inchado :) algorítmica de Java em um cálculo de hash inútil eu não preciso porque eu tenho um espaço fundamental de 1 e nem sequer pretende mapear relacionalmente as três referências, mas apenas para agrupá-los? Com essa implementação, eu tenho que retirar os valores da seguinte maneira:

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);
}

Eu tenho certeza que cada ser capaz de razão senciente aqui provavelmente pensa que esta é uma maneira ridícula para fazê-lo, então a questão é - qual é o caminho certo? :) Eu não posso encontrar evidências de um lugar java.util.Pair ou java.util.Triplet.

Eu suponho uma maneira ortodoxa (TM) seria fazer uma classe personalizada ou interface apenas com a finalidade de habitação este tripleto, mas por uma pequena tarefa tão em um sistema tão grande que parece absurdamente detalhado e desnecessário - embora, em seguida, novamente, isso é próprio Java.

Da mesma forma, talvez os valores podem ser colocados em um ArrayList ou um vetor ou derivado, mas em Java isso não deu uma forma mais concisa de enfrentá-los do que eu vou sair desta HashMap aqui, embora isso não resolve a questão da complexidade algorítmica talvez.

De volta a terra Perl, que tinha acabado de fazer isso usando uma referência de matriz como um valor dentro de um array:

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

O que é o melhor equivalente em Java?

Foi útil?

Solução

Porque não basta criar suas próprias classes pares ou triplos genéricos? Praticamente extremidades do projeto cada Java 5+ até tê-los em seu próprio util aulas!

Outras dicas

Você diz que uma classe personalizada para segurar o trio seria inchado e desnecessária, mas esta é realmente a maneira de fazê-lo, isso é como funciona a modelagem orientada a objetos. A classe personalizada é explícito e legível, e ocupa recursos não mais de tempo de execução do que uma classe titular genéricos.

Java funcional tem pares , trigêmeos , e tuplas até arity 8. Há também um tipo chamado HList para arity arbitrária. Portanto, o seu tipo seria:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

Esta é apenas uma biblioteca, por isso cair o frasco em seu caminho de classe e você está pronto para ir.

Você pode simplesmente usar um ArrayList para armazenar os objetos, desde que você saiba qual objeto será em que localização. Criando uma nova classe com os membros SelectableChannel e ComponentSocketBasis para o provavelmente seria melhor.

Se você vai estar fazendo esse tipo de coisa muito, criando um par ou tupla genérico agora você vai economizar muito tempo, mas se este é o único lugar que você está indo para usá-lo, em seguida, criando uma nova classe irá resultar em muito mais fácil de ler o código.

Sempre que você vê o seu nome de classe no código, você saberá exatamente o que é para, ao passo que se você acabou de ver a sua amálgama genérico, pode ser mais difícil para você (ou alguém) para fazer sentido do que ele está sendo usado para .

É uma troca entre tempo e legibilidade de programação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top