【问题标题】:How to iterate through Nested Map and Multiset? - Java/Guava如何遍历嵌套地图和多重集? - Java/番石榴
【发布时间】:2012-01-21 06:39:35
【问题描述】:

我应该如何使用这样的声明遍历嵌套地图?

  • Map<String, Multiset<String>>

请建议是否有其他哈希图/列表可以更有效地执行此哈希填充任务?

import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultiset;

String[] foobarness = {"foo" , "bar", "ness", "foo", 
    "bar", "foo", "ness", "bar", "foo", "ness", "foo", 
    "bar", "foo", "ness", "bar", "ness", "foo", "bar", 
    "foo", "ness"};
String[] types = {"type::1", "type::2", "type::3", 
    "type::4",};

Map<String, Multiset<String>> typeTextCount = 
new HashMap<String, Multiset<String>>();

Multiset<String> textAndCount 
    = TreeMultiset.create();

for (int i=0; i<types.length; i++) {
    // I know it's kinda weird but in my task, 
    //  i want to keep adding only 1 to the count for each entry.
    // Please suggest if there is a better hashmap/list for such task.
    if ((types[i]== "type::1") or (types[i]== "type::3")) {
        for (String text : foobarness) {
            // I don't worry too much about how i 
            //  populate the Map, it is iterating through 
            //  the Map that I have problem with.           
            textAndCount.put(text, 1); 
        }
    }

    if ((types[i]== "type::2") or (types[i]== "type::4")) {
        for (String text : foobarness) 
            textAndCount.put(text, 1);
    }
}

那么现在哈希图已经被填充了,我该如何遍历那个复杂的嵌套图呢? 我已经尝试了下面的代码,但我只从我的 Multiset 中获得了第一个 getValue():

Iterator<Entry<String, Multiset<String>>> itTTC = 
    typeTextCount.entrySet().iterator();
while (itTTC.hasNext()) {
    Map.Entry textCt = (Map.Entry)itTTC.next();
    System.out.println(textCt.getKey() + " :\t" + textCt.getValue());
    itTTC.remove();
}

【问题讨论】:

  • 您将元素放在地图的什么位置?
  • 顺便问一下,你试过调试器吗?

标签: java map hashmap guava multiset


【解决方案1】:

在您的代码中,您没有将您的Multiset 添加到您的Map。这就是您看不到任何输出的原因。

在你的代码中我这样做了:

typeTextCount.put(types[i], textAndCount);

在循环内部,然后使用相同的迭代器,我可以看到这样的所有输出:

type::3 :   [bar x 24, foo x 32, ness x 24]
type::2 :   [bar x 24, foo x 32, ness x 24]
type::4 :   [bar x 24, foo x 32, ness x 24]
type::1 :   [bar x 24, foo x 32, ness x 24]

编辑:完整代码供参考:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.google.common.collect.Multiset;
import com.google.common.collect.TreeMultiset;

public class TestIterator {

    private static String[] foobarness  =
                                   {
            "foo", "bar", "ness", "foo", "bar", "foo", "ness", "bar", "foo", "ness", "foo", "bar", "foo", "ness",
            "bar", "ness", "foo", "bar", "foo", "ness"
                                   };
    private static String[] types      =
                                   {
            "type::1", "type::2", "type::3", "type::4",
                                   };
    public static void main(String[] args) {
        Map<String, Multiset<String>> typeTextCount = new HashMap<String, Multiset<String>>();

        Multiset<String> textAndCount = TreeMultiset.create();

        for (int i = 0; i < types.length; i++) {
            // I know it's kinda weird but in my task,
            // I want to keep adding only 1 to the count for each entry.
            // Please suggest if there is a better hashmap/list for such task.
            if (("type::1".equals(types[i])) || ("type::3".equals(types[i]))) {
                for (String text : foobarness) {
                    // I don't worry too much about how i
                    // populate the Map, it is iterating through
                    // the Map that I have problem with.
                    textAndCount.add(text, 1);
                }
            }

            if (("type::2".equals(types[i])) || ("type::4".equals(types[i]))) {
                for (String text : foobarness)
                    textAndCount.add(text, 1);
            }
            typeTextCount.put(types[i], textAndCount);
        }

        Iterator<Entry<String, Multiset<String>>> itTTC = typeTextCount.entrySet().iterator();
        while (itTTC.hasNext()) {
            Map.Entry textCt = (Map.Entry) itTTC.next();
            System.out.println(textCt.getKey() + " :\t" + textCt.getValue());
            itTTC.remove();
        }
    }
}

【讨论】:

  • 我只想指出,您仍在使用 == 进行字符串相等,这几乎可以肯定是一个可怕的想法。
  • 已更正谢谢 :) 之前的 OP 代码没有太大变化,但那是一个完美的眼睛 ;)
  • 在 == 上注明。 =) ,坏习惯很难改掉,被regexy perl、stringy python和texty prolog宠坏了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多