How to iterate over multimap in input order?

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

How do I iterate over MultiMap for each key in insertion order?

for instance

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"); 

In every cycle I need

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

then the next cycle

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

etc.:

 "value3", "value33", "value333"; 
+6
source share
4 answers

I'm not quite sure what your needs are (or a specific use case), but I will try to guess. Other answers suggest using Linked * Multimap or Immutable, but to get the desired result (shown in the question) using Multimap you will need to create some kind of fancy map (I will talk about this later) or, for example, create three temporary meetings, the second and the third value for each key (they will be in the input order if you use one of the proposed Multimap implementations). Preferably this will be one of ListMultimaps , as you can ListMultimaps over multimap.keySet() to get lists with values ​​available by index:

 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 disadvantage is that you will need to create three lists for example, which makes this solution rather inflexible. So maybe it's better to post the {First, Second, Third} collection of values ​​in Map> which brings me to the point:


Perhaps you should use Table ?

A table is created as a collection that associates an ordered key pair, called a row key and a column key, with a single value and, more importantly here, has representations of rows and columns. I will use ArrayTable here:

 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 intentionally used String for the string keys, which are [1, 2, 3, ...]. Integers (for example, what you did in the question) and integers for column columns starting at 0 ([0, 1, 2, ...]) to show similarities to the previous example using List get(int) in the value collection multimaps.

Hope this will be useful, mainly when deciding what you want;)

PS I use ArrayTable here because it has an easier way to create a fixed set (universe) of string / key values ​​than ImmutableTable , but if mutability is not required you should use it instead of a single change - ImmutableTable (and any other table implementation) does not have columnKeyList() method, but only columnKeySet() , which does the same thing, but slower for ArrayTable . And of course, ImmutableTable.Builder or ImmutableTable.copyOf(Table) .

+11
source

You can use LinkedListMultimap or LinkedHashMultimap .

Both have very similar behavior; one of the main differences is that LinkedListMultimap allows you to insert multiple copies of the same key-value pair, while LinkedHashMultimap allows only one.

See the above Javadoc for more details.

+4
source

I don't quite understand what iterative order you mean, OP ...

  • Set<K> keySet() just returns the keys.
  • Map<K, Collection<V>> asMap() returns the keys and their associated records, so you can do for (Map.Entry<K, Collection<V>> entry : asMap().entrySet()) to for (Map.Entry<K, Collection<V>> entry : asMap().entrySet()) keys and related collections.
  • Collection<Map.Entry<K, V>> entries() allows you to Collection<Map.Entry<K, V>> entries() over entries, but it is not necessary to group them by keywords.

If you want something in insertion order, use one of the implemented Multimap implementations - LinkedHashMultimap , possibly LinkedListMultimap , ImmutableMultimap .

+3
source

To cyclize multiple keys:

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

You can also iterate over entries:

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

Source: https://habr.com/ru/post/911020/


All Articles