我正在尝试使用番石榴,我遇到了一个问题,我对我找到的解决方案感到不舒服。
在我的情况下,我为每个用户和服务器设置了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);
}
似乎我的方向错误,如果声明令人震惊。好了,
有没有更好的方法将迭代器转换为Table,例如FluentIterator?
您认为如何使用ThreadLocal或Guava Supplier等初始值方法?
由于
答案 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>