7

所以,我只是在阅读 javadocArrayListMultimapLinkedListMultimap了解如何使用它们,我才知道两者都支持重复的键值对(我的意思是相同的键,不同的值 - 如果我理解正确的话。请更正如果我错了我)。但是,我不明白它们之间的区别。两者都用于存储重复的键值对。它们唯一不同的部分是它们的实现,即ArrayListMultimap实现为数组并LinkedListMultimap实现为 LinkedList?另外,它们在性能上有何不同?我知道我问了很多,但我真的不知道在哪里可以找到答案。

4

1 回答 1

25

它在文档中......和代码中。基本上除了您已经看到的一个差异(List实现选择)之外,它们还使用不同的Map实现。所以:

  • ArrayListMultimap用于HashMapmap 和cor 集合,表示或ArrayList等方法的迭代顺序未定义。这是简单明了的实现,您应该从这个开始。entries()asMap().keySet()asMap.entrySet()ListMultimap
  • LinkedListMultimap用于LinkedList集合和专用数据结构(自定义链表)以维护上述方法的迭代顺序:

    使用包含所有键值对的链表来维护顺序。此外,一系列不相交的“兄弟”链表,每个包含特定键的值,用于在恒定时间内实现ValueForKeyIterator 。

    此外,它使用很少的其他结构来维护类似“链表”的行为:

    private transient Node<K, V> head; // the head for all keys
    private transient Node<K, V> tail; // the tail for all keys
    private transient Multiset<K> keyCount; // the number of values for each key
    private transient Map<K, Node<K, V>> keyToKeyHead; // the head for a given key
    private transient Map<K, Node<K, V>> keyToKeyTail; // the tail for a given key
    

此外,内存占用是这些Multimap实现中使用的支持集合的含义 -请参阅此比较(可能不是 100% 最新的)。


就个人而言,当我需要高效、可变ListMultimap且具有已定义的键迭代顺序时,我使用“自定义” ListMultimap(使用创建MultimapBuilder,自 v16.0 以来在 Guava 中创建):

ListMultimap<String, Integer> treeListMultimap = 
    MultimapBuilder.linkedHashKeys().arrayListValues().build();

在 v16.0 之前,创建自定义Multimaps 更加冗长(使用Multimaps.newListMultimap):

/**
 * Creates {@link ListMultimap} preserving insertion order of keys and values 
 * (it's backed by {@link LinkedHashMap} and {@link ArrayList}).
 */
public static <K, V> ListMultimap<K, V> newLinkedArrayListMultimap() {
  return Multimaps.newListMultimap(
      Maps.<K, Collection<V>>newLinkedHashMap(),
      new Supplier<List<V>>() {
          @Override
          public List<V> get() {
            return Lists.newArrayList();
          }
      });
}
于 2013-02-20T09:17:49.273 回答