Question

For each key in a Guava Multimap I need to take the corresponding values and make pairs with them that are not dependent on order.Uniqueness of pairs are not dependent on order for make pairs inside of key. [A,B] = [B,A]. If the pair [B,A] is found in another key then this should treated as another pair. I don't know how iterate the values so I can print out pairs that aren't dependent on order. I'm not sure how to index this either. For arrays, I could just use a double loop.

Here is an example Multimap:

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

I want to take that data and change it to this format. Look carefully, I'm trying to take the values of each key and make pairs.

I want take the first value in the each key and pair it up with the other values. Take the second value and pair it with the value after. Until there no more unique pairs.

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
Was it helpful?

Solution 2

There's two parts to this question, now that I understand it, and really the fact that you're working with Multimaps isn't very important. It's valuable to try to break problems into its component parts; when you do the problems often become clearer, even trivial seeming.

  1. How do I print successive pairs from a collection?

    We need to define a function which will take a Collection (this will let us work with arbitrary Multimaps), and generate your pairs:

    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;
    }
    

    Demo:

    for(String pair : genPairs(ImmutableList.of(1,2,3))) {
      System.out.println(pair);
    }
    
    1, 2
    1, 3
    2, 3
    
  2. How do I print successive pairs from the values of a Multimap?

    This part's easy, you just loop over the value collections and call the above function:

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

OTHER TIPS

I wrote this answer before the question was updated to more clearly describe the desired behavior, however I suspect this answer will still help some people who stumble on this question trying to understand different ways to iterate over a Multimap, so I'm leaving this answer here for posterity. See my other answer for what OP was actually looking for.


Suppose we start with the following Multimap:

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

We can print it's contents several ways, let's try them:

  1. As a raw string:

     map.toString()
    
    {one=[1], several=[1, 2, 3], many=[1, 2, 3, 4, 5]}
    
  2. As a collection of key => collection pairs, with unique keys:

     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());
     }
    
    one: [1]
    
     several: [1, 2, 3]
     many: [1, 2, 3, 4, 5]
    
  3. As a collection of key => value pairs, with duplicate keys (and possibly values, if it's a ListMultimap):

     for(Entry<String, Integer> e : map.entries()) {
       System.out.println(e.getKey()+": "+e.getValue());
     }
    
    one: 1
    
     several: 1
     several: 2
     several: 3
     many: 1
     many: 2
     many: 3
     many: 4
     many: 5
    
  4. As a collection of values, without concern for their keys:

     for(Integer v : map.values()) {
       System.out.println(v);
     }
    
    1
    
     1
     2
     3
     1
     2
     3
     4
     5
    

Those are generally the ways you'd work with a Multimap. You say you're trying to "print out pairs that aren't dependent on order" - it's unclear to me what that means, but if you're saying you want the output of option 3 to be in an arbitrary order, you could write your strings to a list, then shuffle it, like so:

List<String> pairs = new ArrayList<>();
for(Entry<String, Integer> e : map.entries()) {
  pairs.add(e.getKey()+": "+e.getValue());
}
Collections.shuffle(pairs);
for(String s : pairs) {
  System.out.println(s);
}

This would print your Multimap's contents as pairs in arbitrary order.

Hope this helps...

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();
        }
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top