Java 如何按插入顺序迭代Multimap?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9756399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:14:09  来源:igfitidea点击:

How to iterate over Multimap in insertion order?

javaguava

提问by KJW

Using the new collections from Google's Guava, http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained

使用来自 Google Guava 的新集合,http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained

How do I loop over a MultiMap for each key in the order of insertion?

如何按插入顺序为每个键循环 MultiMap?

For example

例如

multimap = new HashMultiMap<String,String>();
multimap.put("1", "value1");
multimap.put("1", "value2");
multimap.put("1", "value3");

multimap.put("2", "value11");
multimap.put("2", "value22");
multimap.put("2", "value33");

multimap.put("3", "value111");
multimap.put("3", "value222");
multimap.put("3", "value333");

On each loop I need

在我需要的每个循环上

"value1", "value11", "value111";

then the next loop

然后下一个循环

"value2", "value22", "value222";

and so on:

等等:

"value3", "value33", "value333";

采纳答案by Xaerxess

I'm not quite sure what are your needs(or concrete use case), but I'll try to guess. Other answers suggest using Linked*Multimap or Immutable one, but to get desired output (shown in question) with Multimapyou will have to create some fancy Map (I'll discuss this later) or for example create three temporary collections holding first, second and third values for each key (they will be in insertion order, if you use one of suggested Multimapimplementations). Preferably it would be one of ListMultimapsas you can iterate over multimap.keySet()to get lists with values available by index:

我不太确定您的需求(或具体用例)是什么,但我会尝试猜测。其他答案建议使用 Linked*Multimap 或 Immutable 一个,但要获得所需的输出(显示在问题中),Multimap您必须创建一些精美的 Map(我将在稍后讨论)或例如创建三个临时集合,其中包含第一个、第二个和每个键的第三个值(如果您使用建议的Multimap实现之一,它们将按插入顺序排列)。最好ListMultimaps是您可以迭代multimap.keySet()以获取具有索引可用值的列表之一:

final ListMultimap<String,String> multimap = LinkedListMultimap.create();
// put values from question here

final List<Object> firstValues = Lists.newArrayList();
for (final String key: multimap.keySet()) {
  firstValues.add(multimap.get(key).get(0));
}    
System.out.println(firstValues);
// prints [value1, value11, value111]
// similar for multimap.get(key).get(1) and so on

but the downside is that you'll have to create three Lists for you example what makes this solution rather unflexible. So maybe it'll be better to put {first,second,third}Values collection to Map>, what brings me to the point:

但缺点是您必须为示例创建三个列表,这使得该解决方案相当不灵活。所以也许将 {first,second,third}Values 集合放到 Map> 中会更好,是什么让我明白了这一点:



Maybe you should use Tableinstead?

也许你应该改用Table

Table is designed as A collection that associates an ordered pair of keys, called a row key and a column key, with a single valueand, what's more important here, has row and column views. I'll use ArrayTablehere:

表被设计为一个集合,它将一对有序的键(称为行键和列键)与单个值相关联,这里更重要的是,具有行和列视图。我会ArrayTable在这里使用:

final ArrayTable<String, Integer, Object> table = ArrayTable.create(
    ImmutableList.of("1", "2", "3"), ImmutableList.of(0, 1, 2));

table.put("1", 0, "value1");
table.put("1", 1, "value2");
table.put("1", 2, "value3");

table.put("2", 0, "value11");
table.put("2", 1, "value22");
table.put("2", 2, "value33");

table.put("3", 0, "value111");
table.put("3", 1, "value222");
table.put("3", 2, "value333");

for (final Integer columnKey : table.columnKeyList()) {
  System.out.println(table.column(columnKey).values());
}
// prints:
// [value1, value11, value111]
// [value2, value22, value222]
// [value3, value33, value333]

I deliberately used String for row keys which are [1, 2, 3, ...] Integers in fact (like you did in the question) and Integers for column keys starting with 0 ([0, 1, 2, ...]) to show similarity to previous example using List's get(int)on multimaps values' collection.

我故意使用 String 作为行键,实际上是 [1, 2, 3, ...] 整数(就像你在问题中所做的那样)和整数作为以 0 开头的列键 ([0, 1, 2, ... ]) 以显示与使用 Listget(int)在多图值集合上的示例的相似性。

Hope this will be helpful, mostly in determining what you want ;)

希望这会有所帮助,主要是确定您想要什么;)

P.S. I use ArrayTablehere, because it has neater way of creating fixed set (universe) of rows / keys values than ImmutableTable, but if mutability isn't required you should use it instead with one change - ImmutableTable(and any other Table implementation) doesn't have columnKeyList()method, but only columnKeySet()which does the same thing, but is slower for ArrayTable. And of course ImmutableTable.Builderor ImmutableTable.copyOf(Table)should be used.

PS 我ArrayTable在这里使用,因为它具有比 更简洁的方式来创建行/键值的固定集(宇宙)ImmutableTable,但是如果不需要可变性,您应该使用它来代替一个更改 - ImmutableTable(以及任何其他表实现)不会havecolumnKeyList()方法,但只columnKeySet()执行相同的操作,但对于ArrayTable. 当然ImmutableTable.Builder或者ImmutableTable.copyOf(Table)应该使用。

回答by ApprenticeHacker

For looping over multiple keys:

对于循环多个键:

for (Object key : multimap.keys()) { ... }

You can also loop over the entries:

您还可以遍历条目:

for (Map.Entry entry : multimap.entries()) { ... }

回答by ruakh

You can use either LinkedListMultimapor LinkedHashMultimap.

您可以使用LinkedListMultimapLinkedHashMultimap

The two have very similar behavior; one major difference is that LinkedListMultimapallows multiple copies of the same key-value pair to be inserted, whereas LinkedHashMultimapallows only one.

两者的行为非常相似;一个主要区别是LinkedListMultimap允许插入同一键值对的多个副本,而LinkedHashMultimap只允许插入一个。

See the above-linked Javadoc for much more information.

有关更多信息,请参阅上面链接的 Javadoc。

回答by Louis Wasserman

I'm not entirely clear what iteration order you mean, OP...

我不完全清楚你的意思是什么迭代顺序,OP ...

  • Set<K> keySet()just returns the keys.
  • Map<K, Collection<V>> asMap()returns the keys and their associated entries, so you might do for (Map.Entry<K, Collection<V>> entry : asMap().entrySet())to iterate over keys and their associated collections.
  • Collection<Map.Entry<K, V>> entries()lets you iterate over the entries, but without necessarily grouping them by key.
  • Set<K> keySet()只返回键。
  • Map<K, Collection<V>> asMap()返回键及其关联的条目,因此您可以for (Map.Entry<K, Collection<V>> entry : asMap().entrySet())迭代键及其关联的集合。
  • Collection<Map.Entry<K, V>> entries()允许您遍历条目,但不必按键对它们进行分组。

If you want things in insertion order, use one of the insertion-ordered Multimapimplementations -- LinkedHashMultimap, possibly LinkedListMultimap, ImmutableMultimap.

如果您想要按插入顺序排列的内容,请使用插入顺序Multimap实现之一 -- LinkedHashMultimap,可能LinkedListMultimapImmutableMultimap