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
How to iterate over Multimap in insertion order?
提问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 Multimap
you 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 Multimap
implementations). Preferably it would be one of ListMultimaps
as 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 ArrayTable
here:
表被设计为一个集合,它将一对有序的键(称为行键和列键)与单个值相关联,这里更重要的是,具有行和列视图。我会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 ArrayTable
here, 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.Builder
or 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 LinkedListMultimap
or LinkedHashMultimap
.
您可以使用LinkedListMultimap
或LinkedHashMultimap
。
The two have very similar behavior; one major difference is that LinkedListMultimap
allows multiple copies of the same key-value pair to be inserted, whereas LinkedHashMultimap
allows 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 dofor (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 Multimap
implementations -- LinkedHashMultimap
, possibly LinkedListMultimap
, ImmutableMultimap
.
如果您想要按插入顺序排列的内容,请使用插入顺序Multimap
实现之一 -- LinkedHashMultimap
,可能LinkedListMultimap
,ImmutableMultimap
。