番石榴表的初始值

时间:2012-12-11 15:17:58

标签: java guava

我正在尝试使用番石榴,我遇到了一个问题,我对我找到的解决方案感到不舒服。

在我的情况下,我为每个用户和服务器设置了id。尽管Guava表有令人难以置信的简化,但我仍然在构造表中的循环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. 有没有更好的方法将迭代器转换为Table,例如FluentIterator?

  2. 您认为如何使用ThreadLocal或Guava Supplier等初始值方法?

  3. 由于

2 个答案:

答案 0 :(得分:3)

由于您要在Table Cell中存储一个集合,因此实际需要的是“多样化”,可根据需要自动为您创建集合(如Multimap所示) 。我非常确定这个要求非常复杂,超出了番石榴团队愿意实施的范围。

我会说你正在做的是处理这种情况的最佳方式(当然,除了你的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);

}

答案 1 :(得分:0)

另一种可能性是定义一个同时包含x和y的“key”类。然后,您可以使用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 is useful largely for its complex views, like row() and column().对于get()size()values().iterator()等简单用途,您可以使用Multimap。{/ p>