1

我正在尝试使用 Guava 进行练习,但遇到了一个问题,我对找到的解决方案感到不舒服。

在我的情况下,我为每个用户和服务器设置了 id。尽管 Guava Table 进行了令人难以置信的简化,但if statement block在构造表的循环内部仍然存在问题。

  Table<Integer, Integer, Set> setPerUser = HashBasedTable.create();

  for(Conversation conversation : conversations) {
     Set uci = setPerUser.get(conversation.x, conversation.y);
     if(uci == null) {
        uci = new HashSet();
        setPerUser.put(conversation.x, conversation.y, uci);
     }
     uci.add(conversation.id);
  }

看来我的方向是错误的,如果陈述使情况令人震惊。行,

  1. 有没有更好的方法将迭代器转换为 FluentIterator 等 Table?

  2. 你觉得有 ThreadLocal 或 Guava Supplier 之类的初值方法是什么?

谢谢

4

2 回答 2

3

由于您将集合存储在您Table Cell的 s 中,因此您实际需要的是一个“多表”,它会根据需要自动为您创建集合(就像Multimap那样)。我很确定这个要求足够复杂,超出了 Guava 团队愿意实现的范围。

我想说你正在做的是处理这种情况的最好方法(除了你的 Set 应该是通用的,当然)

这是一个静态工厂方法,它以更通用的方式完成您想做的事情:

public static <X, Y, Z, S extends Collection<Z>> void addCellValue(
    Table<X, Y, S> table, X rowKey, Y colKey, Z value, Supplier<S> supplier) {

    final S data;
    if (table.contains(rowKey, colKey)) {
        data = table.get(rowKey, colKey);
    } else {
        data = supplier.get();
        table.put(rowKey, colKey, data);
    }
    data.add(value);

}
于 2012-12-11T15:24:59.573 回答
0

另一种可能性是定义一个包含 x 和 y 的“关键”类。然后你可以使用Multimap

final class ConversationId {
  private final Integer userId;
  private final Integer serverId;

  // constructor, equals(), hashCode() ...
}

SetMultimap<ConversationId, V> conversationsById = HashMultimap.create();
// populate...

现在创建和填充的代码Multimap看起来很像Multimaps.index. 您可以改为:

Multimap<ConversationId, V> conversationsById = Multimaps.index(conversations, idFunction());

单键Multimap不提供双键的所有功能Table,但这对于您的用例可能没问题。Table主要是因为它的复杂视图,比如row()column()对于简单的用途,如get(),size()values().iterator(),您可以使用Multimap.

于 2012-12-11T17:30:32.457 回答