Comment insérer une & # 8220; paire & # 8221; ou n-size dans une collection de liste au lieu de composer HashMaps?

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

Question

J'ai donc une situation où il me faut passer trois valeurs dans une file d'attente sérielle BlockingQueue:

(SelectableChannel, ComponentSocketBasis, Integer).

Ils n’ont en fait pas besoin d’être mappés en hash, et utiliser un HashMap est ridicule car il n’y aura toujours qu’une clé pour chaque entrée; ce serait bien s'ils étaient juste dans une sorte de jeu ordonné. Toutefois, faute d’une alternative connue, j’ai utilisé une carte de hachage dans ma mise en œuvre et produit cette composition générique masquée:

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

Cela semble vraiment ridicule. Je dois être un terrible N00B. Il existe sûrement un meilleur moyen de le faire qui ne nécessite pas de décomposer la clé lors de la récupération des valeurs ou de le gaspiller (théorique - en pratique, la complexité algorithmique de Java toujours gonflée :) sur un calcul de hachage inutile dont je n'ai pas besoin. parce que j'ai un espace clé de 1 et que je ne veux même pas cartographier relationnellement les trois références, mais simplement les regrouper? Avec cette implémentation, je dois extraire les valeurs de la manière suivante:

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

Je suis à peu près sûr que tout être capable de raison sensible pense probablement que c’est une façon ridicule de le faire, alors la question est la suivante: quelle est la bonne façon? :) Je ne trouve aucune preuve d'un java.util.Pair ou d'un java.util.Triplet où que ce soit.

Je suppose qu’une manière orthodoxe consisterait à créer une classe ou une interface personnalisée dans le seul but de loger ce triplet, mais pour une tâche aussi petite dans un système aussi vaste, cela semble absurdement verbeux et inutile. là encore, c'est Java lui-même.

De même, les valeurs peuvent peut-être être placées dans un ArrayList ou un vecteur ou un dérivé de celui-ci, mais en Java, cela ne donne pas une façon plus concise de les traiter que je ne parviens à en sortir ici, même si cela résout peut-être le problème de complexité algorithmique.

De retour au pays Perl, nous le ferions simplement en utilisant une référence de tableau comme valeur dans un tableau:

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

Quel est le meilleur équivalent en Java?

Était-ce utile?

La solution

Pourquoi ne pas simplement créer votre propre classe générique Pair ou Triple classes? Pratiquement tous les projets Java 5+ finissent par les avoir dans leurs propres classes d’utilisation!

Autres conseils

Vous dites qu'une classe personnalisée contenant le triplet serait surchargée et inutile, mais c'est vraiment la façon de le faire, c'est ainsi que fonctionne la modélisation orientée objet. Une classe personnalisée est explicite et lisible et ne prend pas plus de ressources d’exécution qu’une classe générique de titulaire.

Java fonctionnel a paires , triplets et des n-uplets jusqu’à arity 8. Il existe également un type appelé HList pour une arité arbitraire. Donc, votre type serait:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

Ceci est juste une bibliothèque, alors déposez le fichier jar dans votre chemin de classe et vous êtes prêt à partir.

Vous pouvez simplement utiliser une liste de tableaux pour stocker les objets, car vous savez quel objet sera à quel emplacement. Créer une nouvelle classe avec les membres SelectableChannel et ComponentSocketBasis pour le serait probablement mieux.

Si vous envisagez de faire beaucoup de choses de ce genre, créer un couple ou un tuple générique vous fera gagner beaucoup de temps, mais si c'est le seul endroit où vous allez l'utiliser, alors la création d'une nouvelle classe rendra le code beaucoup plus facile à lire.

Chaque fois que vous verrez votre nom de classe dans le code, vous saurez exactement à quoi il sert, alors que si vous voyez simplement votre fusion générique, il sera peut-être plus difficile pour vous (ou pour quelqu'un d'autre) de comprendre à quoi cela sert. .

C’est un compromis entre temps de programmation et lisibilité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top