2011-03-16 91 views
2

我想从哈希映射中检索k,v对。 entrys是这样的:递归迭代哈希映射

a = 3,4 
b = 5,6 

等等。我需要这些值的组合。

a=3, b=5. 
a=3, b=6. 
a=4, b=5. 
a=4, b=6. 

我不知道值多少个键,多少entrys有。与入口集我可以得到的价值,但不是组合。它看起来像递归,但如何?

这里是我的代码:

HashMap<String, String[]> map = new HashMap<String, String[]>(); 

BufferedReader file = new BufferedReader(new FileReader("test.txt")); 
String str; 


while ((str = file.readLine()) != null) { 


    ... logic 


    map.put(key, value); 



} 
System.out.println("number of keys: " + map.size()); 
for(Entry<String, String[]> entry : map.entrySet()) { 
    for(String value : entry.getValue()) { 
     System.out.println(entry.getKey() + ": " + value); 
    } 
} 
file.close(); 
+0

我不清楚:“a”是你的钥匙和“3”(从列表中)你的价值,或者是“3”你的钥匙是从a和“5”你的价值? – 2011-03-16 09:10:44

+0

a是关键,3和4是字符串。因此“String []”。值是String [] – zyamat 2011-03-16 09:18:12

回答

0

它看起来像你对我真的想要一个MultiMap。特别是,ArrayListMultimap允许重复的条目:

ArrayListMultimap<String, String> map = ArrayListMultimap.create(); 

for each line in file: 
    parse key k 
    for each value in line: 
     parse value v 
     map.put(k, v); 

for (Map.Entry<String,String> entry : map.entries()) { 
    String key = entry.getKey(); 
    String value = entry.getValue(); 
} 

如果你想图的笛卡尔积,可以计算直接使用递归,或者你可以遍历地图:创建迭代和迭代的列表里程表风格;当迭代器N达到其结束时,推进迭代器N + 1并重置迭代器1..N。


只是戳了一圈,发现这太问题:Iterative Cartesian Product in Java

所以我建议你使用番石榴的Sets.cartesianProduct对笛卡尔乘积。这里是我的代码周围戳,你可以适应您的输入逻辑:

String key1 = "a"; 
    Set<Integer> values1 = Sets.newLinkedHashSet(Arrays.asList(1, 2, 3, 4)); 
    String key2 = "b"; 
    Set<Integer> values2 = Sets.newLinkedHashSet(Arrays.asList(5, 6, 7)); 
    String key3 = "c"; 
    Set<Integer> values3 = Sets.newLinkedHashSet(Arrays.asList(8, 9)); 

    List<String> keys = Arrays.asList(key1, key2, key3); 
    Set<List<Integer>> product = Sets.cartesianProduct(values1, values2, values3); 
    for (List<Integer> values : product) { 
     for (int i = 0; i < keys.size(); ++i) { 
      String key = keys.get(i); 
      int value = values.get(i); 
      System.out.print(key + "=" + value + "; "); 
     } 
     System.out.println(); 
    } 
+0

我不希望重复的条目。我只想每个K,V组合。我不关心什么是价值观。 – zyamat 2011-03-16 09:19:17

+0

'HashMultimap'将防止重复的条目。但是我对你的目标还是很不清楚。 – 2011-03-16 09:22:00

+0

好的。我得到一个文本输入。这将进入地图。关键是一个。这些值存储在一个String []中。我以后需要将这些值作为单独的字符串。所以这就是为什么它是String []而不仅仅是字符串。在我的第一篇文章中,我需要从键值对的每个组合。 – zyamat 2011-03-16 09:25:01

5

你可以试试下面的代码:

public void mapPermute(Map<String, String[]> map, String currentPermutation) { 
    String key = map.keySet().iterator().next(); // get the topmost key 

    // base case 
    if (map.size() == 1) {   
     for (String value : map.get(key)) { 
      System.out.println(currentPermutation + key + "=" + value); 
     } 
    } else { 
     // recursive case 
     Map<String, String[]> subMap = new HashMap<String, String[]>(map); 

     for (String value : subMap.remove(key)) { 
      mapPermute(subMap, currentPermutation + key + "=" + value + ", "); 
     } 
    } 
} 

内存效率和速度没有保证。如果要保留地图中按键的顺序,则必须在递归情况下传递TreeMap并将代码更改为使用TreeMap

正如基本案例所示,我假设您至少在地图上有一个条目。

+0

这绝对完美!按预期工作!非常感谢你! – zyamat 2011-03-16 11:38:04