0

所以,我有一种情况,我需要将三个值传递到串行 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 的证据。

我想 Orthodox Way(TM) 会做一个自定义类或接口,只是为了容纳这个三元组,但是对于这么大的系统中这么小的任务,这似乎是荒谬的冗长和不必要的——不过,再说一次,那就是Java本身。

出于同样的原因,也许这些值可以放在一个 ArrayList 或一个 Vector 或其衍生物上,但在 Java 中,这并没有产生比我在这里摆脱这个 HashMap 更简洁的方法来解决它们,尽管它确实解决了也许是算法复杂性问题。

回到 Perl 领域,我们只需将数组引用用作数组中的值即可:

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

Java中最好的等价物是什么?

4

4 回答 4

5

为什么不创建自己的通用 Pair 或 Triple 类?几乎每个 Java 5+ 项目最终都将它们放在自己的 util 类中!

于 2009-05-07T15:35:19.457 回答
4

您说保存三元组的自定义类会变得臃肿且不必要,但这确实是这样做的方式,这就是面向对象建模的工作方式。自定义类是显式且可读的,并且不会比通用持有者类占用更多的运行时资源。

于 2009-05-07T15:39:52.783 回答
2

函数式 Javapairtriplets和 tuples 到 arity 8。还有一种类型称为HListarity arity。所以你的类型是:

LinkedBlockingQueue<P3<SelectableChannel, ComponentSocketBasis, Integer>>

这只是一个库,所以把 jar 放到你的类路径中就可以了。

于 2009-05-07T15:45:58.650 回答
2

您可以只使用 ArrayList 来存储对象,因为您知道哪个对象将在哪个位置。使用成员 SelectableChannel 和 ComponentSocketBasis 创建一个新类可能会更好。

如果你要经常做这种事情,现在创建一个泛型对或元组将节省你很多时间,但如果这是你将要使用它的唯一地方,那么创建一个新的类将导致更容易阅读代码。

每当您在代码中看到您的类名时,您就会确切地知道它的用途,而如果您只是看到您的通用合并,您(或其他人)可能更难理解它的用途。

这是编程时间和可读性之间的权衡。

于 2009-05-07T15:58:02.380 回答