title: Efficiency of guava Table vs multiple hash maps
body: <p>I ran across some code that was doing something like this:</p>
  
  <pre><code>Map&lt;String,String&gt; fullNameById = buildMap1(dataSource1);
  Map&lt;String,String&gt; nameById = buildMap2(dataSource2);
  Map&lt;String,String&gt; nameByFullName = new HashMap&lt;String,String&gt;();
  Map&lt;String,String&gt; idByName = new HashMap&lt;String,String&gt;();
  
  Set&lt;String&gt; ids = fullNameById.keySet();
  for (String nextId : ids) {
    String name = nameById.get(nextId);
    String fullName = fullNameById.get(nextId);
    nameByFullName.put(fullName, name);
    idByName.put(name, nextId);
  }
  </code></pre>
  
  <p>I had to stare at it for several minutes to figure out what was going on. All of that amounts to a join operation on id's and an inversion of one of the original maps. Since Id, FullName and Name are always 1:1:1 it seemed to me that there should be some way to simplify this. I also discovered that the first two maps are never used again, and I find that the above code is a bit hard to read. So I'm considering replacing it with something like this that (to me) reads much cleaner </p>
  
  <pre><code>Table&lt;String, String, String&gt; relations = HashBasedTable.create();
  
  addRelationships1(dataSource1, relations);
  addRelationships2(dataSource2, relations);
  
  Map&lt;String,String&gt; idByName = relations.column("hasId");
  Map&lt;String,String&gt; nameByFullName = relations.column("hasName");
  relations = null; // not used hereafter
  </code></pre>
  
  <p>In addRelationships1 I do</p>
  
  <pre><code>relations.put(id, "hasFullName", fullname);
  </code></pre>
  
  <p>And in addRelationships2 where my query yields values for <code>id</code> and <code>name</code> I do</p>
  
  <pre><code>relations.put(relations.remove(id,"hasFullName"), "hasName", name);
  relations.put(name, "hasId", id);
  </code></pre>
  
  <p>So my questions are these:</p>
  
  <ol>
  <li>Is there a lurking inefficiency in what I have done either via processor or memory, or GC load? I don't think so, but I'm not that familiar with the efficiency of Table. I am aware that the Table object won't be GC'd after <code>relations = null</code>, I just want to communicate that it's not used again in the rather lengthy section of code that follows.</li>
  <li>Have I gained any efficiency? I keep convincing and unconvincing myself that I have and have not.</li>
  <li>Do you find this more readable? Or is this only easy for me to read because I wrote it? I'm a tad worried on that front due to the fact <code>Table</code> is not well known. On the other hand, the top level now pretty clearly says, "gather data from two sources and make these two maps from it." I also like the fact that it doesn't leave  you wondering if/where the other two maps are being used (or not).</li>
  <li>Do you have an even better, cleaner, faster, simpler way to do it than either of the above?</li>
  </ol>
  
  <p>Please Lets not have the optimize early/late discussion here. I'm well aware of that pitfall. If it improves readability without hurting performance I am satisfied. Performance gain would be a nice bonus.</p>
  
  <p><strong>Note:</strong> my variable and method names have been sanitized here to keep the business area from distracting from the discussion, I definitely won't name them addRelationships1 or datasource1! Similarly, the final code will of course use constants not raw strings.</p>