So, I have a situation where I need to pass in three values into a serial BlockingQueue queue:
(SelectableChannel, ComponentSocketBasis, Integer).
They don't actually need to be hash mapped at all, and to use a HashMap is ridiculous as there will always be only one key for each entry; it'd be fine if they were just in some sort of ordered set. For lack of a known alternative, however, I used a HashMap in my implementation and produced this obfuscated generics composition:
private LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>> deferredPollQueue = new LinkedBlockingQueue<HashMap<HashMap<SelectableChannel, ComponentSocketBasis>, Integer>>();
This seems really ridiculous. I must be a terrible n00b. Surely there is a better way to do this that doesn't require me to decompose the key when retrieving the values or waste the (theoretical--in practice, Java's always bloated :) algorithmic complexity on a useless hash computation I don't need because I have a key space of 1 and don't even want to relationally map the three references, but merely to group them? With this implementation, I have to pull out the values thusly:
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);
}
I am pretty sure every being capable of sentient reason here probably thinks this is a ridiculous way to do it, so the question is - what's the right way? :) I can't find evidence of a java.util.Pair or java.util.Triplet anywhere.
I suppose an Orthodox Way(TM) would be to do a custom class or interface just for the purpose of housing this triplet, but for such a small task in such a large system this seems preposterously verbose and unecessary--though, then again, that's Java itself.
By the same token, perhaps the values can be put onto an ArrayList or a Vector or derivative thereof, but in Java this does not yield a more terse way of addressing them than I'm getting out of this HashMap here, though it does solve the algorithmic complexity issue perhaps.
Back in Perl land, we'd just do this by using an array reference as a value inside an array:
push(@$big_queue_array, [$elem1, \%elem2, \@elem3]);
What's the best equivalent in Java?