如何迭代Guava多重映射以成对打印出值

时间:2014-05-06 00:05:44

标签: java iteration guava multimap

对于Guava Multimap中的每个键,我需要获取相应的值并与它们成对,而不依赖于order。对的唯一性不依赖于键内的make对的顺序。 [A,B] = [B,A]。如果在另一个密钥中找到对[B,A],那么这应该被视为另一对。我不知道如何迭代这些值,这样我就可以打印出不依赖于顺序的对。我也不确定如何将其编入索引。对于数组,我可以使用双循环。

以下是Multimap的示例:

BE0004429: [DB00515, DB00951, DB01582]
BE0000059: [DB00603, DB01285]
BE0001052: [DB00366, DB00472, DB00856, DB01104, DB01149]

我想获取该数据并将其更改为此格式。仔细观察,我试图获取每个键的值并进行配对。

我想取每个键中的第一个值并将其与其他值配对。取第二个值并将其与后面的值配对。直到没有更多独特的对。

DB00515, DB00951
DB00515, DB01582
DB01582, DB00951

DB00603, DB01285

DB00366, DB00472
DB00366, DB00856
DB00366, DB01104
DB00366, DB01149
DB00472, DB00856
DB00472, DB01104
DB00472, DB01149
DB00856, DB01104
DB00856, DB01149
DB01104, DB01149

3 个答案:

答案 0 :(得分:5)

这个问题有两个部分,现在我明白了,而且你使用Multimaps的事实并不是很重要。尝试将问题分解为其组成部分是很有价值的;当你这样做时,问题往往会变得更加清晰,甚至是微不足道的。

  1. 如何从集合中打印连续的对?

    我们需要定义一个将采用Collection的函数(这将让我们使用任意Multimaps),并生成你的对:

    public static <V> List<String> genPairs(Collection<V> col) {
      List<V> ls = ImmutableList.copyOf(col);
      List<String> ret = new ArrayList<>();
    
      for (int i = 0; i < ls.size()-1; i++) {
        for (int j = i+1; j < ls.size(); j++) {
          ret.add(ls.get(i)+", "+ls.get(j));
        }
      }
    
      return ret;
    }
    

    演示:

    for(String pair : genPairs(ImmutableList.of(1,2,3))) {
      System.out.println(pair);
    }
    
    1, 2
    1, 3
    2, 3
    
  2. 如何从Multimap的值中打印连续的对?

    这部分很简单,你只需遍历值集合并调用上面的函数:

    for(Collection<String> col : multimap.asMap().values()) {
      for(String pair : genPairs(col)) {
        System.out.println(pair);
      }
      System.out.println();
    }
    

答案 1 :(得分:4)

我在更新问题之前写了这个答案,以便更清楚地描述所需的行为,但我怀疑这个答案仍然可以帮助一些偶然发现这个问题的人试图理解迭代{{1所以我把这个答案留给了后代。请参阅上面的其他答案,了解OP实际上在寻找什么。


假设我们从以下Multimap开始:

Multimap

我们可以通过多种方式打印它的内容,让我们试一试:

  1. 作为原始字符串:

    Multimap<String, Integer> map = new ImmutableSetMultimap.Builder<String, Integer>()
                                    .put("one", 1)
                                    .putAll("several", 1, 2, 3)
                                    .putAll("many", 1, 2, 3, 4, 5)
                                    .build();
    
    map.toString()
    
  2. 作为key =&gt;的集合集合对,具有唯一键:

    {one=[1], several=[1, 2, 3], many=[1, 2, 3, 4, 5]}
    
    for(String key : map.keySet()) {
      System.out.println(key+": "+map.get(key));
    }
    
    // OR with the asMap() view
    
    for(Entry<String,Collection<Integer> e : map.asMap().entrySet()) {
      System.out.println(e.getKey()+": "+e.getValue());
    }
    
  3. 作为key =&gt;的集合值对,具有重复键(可能是值,如果它是ListMultimap):

    one: [1]
    several: [1, 2, 3]
    many: [1, 2, 3, 4, 5]
    
    for(Entry<String, Integer> e : map.entries()) {
      System.out.println(e.getKey()+": "+e.getValue());
    }
    
  4. 作为值的集合,无需担心其键:

    one: 1
    several: 1
    several: 2
    several: 3
    many: 1
    many: 2
    many: 3
    many: 4
    many: 5
    
    for(Integer v : map.values()) {
      System.out.println(v);
    }
    
  5. 这些通常您使用1 1 2 3 1 2 3 4 5 的方式。你说你试图“打印出不依赖于订单的对” - 我不清楚这意味着什么,但如果你说你希望选项3的输出是任意顺序,你可以将你的字符串写入列表,然后将其洗牌,如下所示:

    Multimap

    这将以任意顺序打印Multimap的内容。

答案 2 :(得分:0)

希望这会有所帮助......

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class GuavaSample {

    public static void main(String[] args) {
        Multimap<String, String> multiMap = ArrayListMultimap.create();
        multiMap.put("BE0004429", "DB00515");
        multiMap.put("BE0004429", "DB00951");
        multiMap.put("BE0004429", "DB01582");

        multiMap.put("BE0000059", "DB00603");
        multiMap.put("BE0000059", "DB01285");

        multiMap.put("BE0001052", "DB00366");
        multiMap.put("BE0001052", "DB00472");
        multiMap.put("BE0001052", "DB00856");
        multiMap.put("BE0001052", "DB01104");
        multiMap.put("BE0001052", "DB01149");

        for (String key : multiMap.keySet()) {
            List<String> list = (List<String>) multiMap.get(key);
            for (int i = 0; i < list.size(); i++) {
                for (int j = i + 1; j < list.size(); j++) {
                    System.out.println(list.get(i) + "," + list.get(j));
                }
            }
            System.out.println();
        }
    }

}