2012-03-12 44 views
2

是否有可能在番石榴,问题与番石榴的BIMAP和LinkedHashMap的

  1. BiMap进行反向查找键和多个值吗?准确地说,我有密钥和相应的多个值,我想从一个值中获取密钥。

  2. 要在LinkedHashMap中存储多个值?确切地说,我想以某种顺序存储,键 - 多个值,因此我可以在列表中获得关键位置。

+0

其实我想解决这个http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference问题。这就是为什么我想用单个“foo”替换所有“foo”,然后反向查找(用于键值多值映射),或者从可节省空间的位置获取键值(用于键 - 多值映射)。但是,看来,我必须浪费比以前更多的空间。有没有这个http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference的番石榴解决方案。谢谢。 – Arpssss 2012-03-12 20:11:51

+1

这种感觉就像你正试图做的不成熟的优化。 – 2012-03-13 03:04:08

回答

6

Ad。 1.我想你想BiMap反向查找(BitMap不存在于番石榴)?是的,这是可能的,你只需拨打inverse在你的BiMap<K, V>,你会得到你的bimap BiMap<V, K>查看

实施例(从番石榴的测试套件截取):

public void testMapConstructor() { 
    /* Test with non-empty Map. */ 
    Map<String, String> map = ImmutableMap.of(
     "canada", "dollar", 
     "chile", "peso", 
     "switzerland", "franc"); 
    HashBiMap<String, String> bimap = HashBiMap.create(map); 
    assertEquals("dollar", bimap.get("canada")); 
    assertEquals("canada", bimap.inverse().get("dollar")); 
} 

广告。 2.假设你的意思是“我想存储,键 - >多[收藏]值”Map<K, Collection<V>>),ListMultimap可能是你想要什么,更precisly ArrayListMultimap(蜜饯值顺序)或LinkedListMultimap(保存键和值订购)。如果你的对象是不可改变的,我强烈建议你使用ImmutableListMultimap

您还可以通过使用factory(有点冗长)创建自己的实现的Multimap,即使用:

private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() { 
    return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(), 
     new Supplier<List<V>>() { 
     @Override public List<V> get() { 
      return Lists.newArrayList(); 
     } 
     }); 
} 

public static void main(final String[] args) { 
    final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap(); 
    multimap.putAll("one", ImmutableList.of("zero", "three")); 
    multimap.putAll("two", ImmutableList.of("three", "four", "three")); 
    multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap 
    multimap.put("four", "forty-two"); 

    System.out.println(multimap); 
    // prints {one=[one, three], two=[three, four, three], four=[forty-two]} 

    final List<String> listForOnes = multimap.get("one"); 
    System.out.println(listForOnes.get(0)); 
    // prints zero 
} 

附:看看Guava's wiki,这是解释BiMap和Multimaps。

+0

谢谢。其实我想解决这个http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference问题。这就是为什么,我想用单个“foo”替换所有“foo”,然后执行反向查找(用于键 - 多值映射),或者从节省空间的位置获取键(用于键 - 多值映射)。但是,从你的答案看来,我必须浪费比以前更多的空间。是否有任何番石榴解决方案http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference。谢谢。 – Arpssss 2012-03-12 20:08:07

3

最靠近的番石榴是Multiset映射多个值的关键,但我怀疑它满足您的要求。

  1. 我怀疑这是个好主意使用的值(当你有多个值映射到单个键),为了做到这一点你的价值应该是唯一的,并考虑你的数据结构(就像Map<Key, Collection<Value>查找关键)它不能保证有独特的价值。
  2. 番石榴的另一个选项是BiMap,它需要唯一的值并且可以提供反向映射(值 - >键),但由于您需要将多个值映射到同一个键,所以这也不太合适。
3

正如@Xaerxess在回答您的第2个问题时所说,您可以使用Multimaps.newListMultimap方法创建自己的ListMultimap,它使用LinkedHashMap作为其支持地图。

对于第一个问题,如果您将键映射到多个值(即Multimap),则可以使用方法Multimaps.invertFrom创建原始Multimap的反转副本以进行反向查找。此外,您可以创建一个ImmutableListMultimap原件副本,并使用其inverse()方法获得相反的结果,虽然这只是要复制原件,就像Multimaps.invertFrom一样(尽管它会缓存它,因此重复调用inverse()会返回相同的副本。)

如果您不介意额外的内存消耗,想要做多次反向查找,并且不需要反向副本以保持与发生的原始更改保持同步,这可能是值得的在你创建它之后。如果您只想查找映射到一个特定值的键,则可以在条目的一次迭代中执行此操作,而无需创建完整副本。

+0

我同意''Multimaps.invertFrom'和'ImmutableXXXMultimap.invert()'是非常有用的。 @OP - 参见我的[用ImmultableListMultimap.invert()'](http://stackoverflow.com/a/8439744/708434)的示例代码回答另一个问题。 – Xaerxess 2012-03-12 18:19:05

+0

@ColinD,Thanks.Actually我想解决这个http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference问题。这就是为什么我想用单个“foo”替换所有“foo”,然后反向查找(用于键值多值映射),或者从可节省空间的位置获取键值(用于键 - 多值映射)。但是,从你的答案看来,我必须浪费比以前更多的空间。是否有任何番石榴解决方案http://stackoverflow.com/questions/9661374/java-hash-table-issue-with-object-refference。谢谢。 – Arpssss 2012-03-12 20:05:12

+0

@Arpssss:我担心在这个问题上,我真的不清楚这个问题,以及那个你真正想做的事情,所以我不确定我能帮助你。在另一个问题中,对我来说,听起来你担心的是你可能不应该担心的事情,但是我再次说不出任何细节。 – ColinD 2012-03-12 20:50:14