简体   繁体   中英

Inital Value for Guava Table

I am trying to practice with Guava and I have come across a problem and I am not comfortable with the solution I have found.

In my situation, I have id set per user and server. Despite of incredible simplification by Guava Table I have still problems inside the loop if statement block in construction table.

  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);
  }

It seems that I have in wrong direction and if statements are alarming the situtation. Ok,

  1. Is there a better way to transform a iterator to Table such as FluentIterator?

  2. What do you think to have an initial value method such as ThreadLocal or Guava Supplier?

Thanks

Since you are storing a collection in your Table Cell s, what you actually need is a "Multitable", that automatically creates Collections for you as needed (as Multimap does). I am pretty sure that this requirement is complex enough to be beyond what the Guava team are willing to implements.

I'd say what you are doing is the best possible way to deal with the situation (apart from the fact that your Set should be generic, of course)

Here's a static factory method that does what you want to do in a more generic way:

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);

}

Another possibility is to define a "key" class that holds both x and y. Then you can use Multimap :

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

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

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

Now the code to create and populate the Multimap looks a lot like Multimaps.index . You could call that instead:

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

The single-keyed Multimap doesn't offer all the functionality of the double-keyed Table , but that may be OK for your use case. Table is useful largely for its complex views, like row() and column() . For simple uses like get() , size() , and values().iterator() , you may be able to get by with Multimap .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM