【问题标题】:Adding an element to an a HashMap in an ArrayList of HashMap in Java将元素添加到Java中HashMap的ArrayList中的HashMap
【发布时间】:2012-09-12 19:03:22
【问题描述】:

我在 Java 中有一个源 HashMap:

HashMap<String, Integer> keyWordFrequencies;

存储各种长度的关键字。我想遍历这个 HashMap 并计算出存储在映射的 String 部分中的 ngram 的长度,该部分定义了每个关键字的文本。

有了这些数据,我想填充 HashMaps 的目标 ArrayList:

ArrayList<HashMap<String, Integer>> keywordNgrams;

根据结果,ArrayList 的索引对应于给定关键字的 ngram 大小减一,即,keywordNGrams(0) 将接收 unigram,keywordNGrams(1) 将接收 bigram,依此类推。但我不确定必要的语法。遍历源 HashMap 很简单:

Set keyWordFrequenciesSet = keyWordFrequencies.entrySet();
Iterator keyWordFrequenciesIterator = keyWordFrequenciesSet.iterator();
while(keyWordFrequenciesIterator.hasNext()) {
   Map.Entry m = (Map.Entry) keyWordFrequenciesIteratorIterator.next();
   int ngramLength = String_Utils.getLengthOfNgram(m.getKey().toString());

   Add element to keywordNgrams?

但是将元素添加到 HashMap 的目标 ArrayList 让我感到困惑。我试过了:

keywordNgrams.add(ngramLength, m);

还有各种选择,但无济于事。 m 应该是 HashMap 的一个元素,而不是 HashMap 本身。谁能建议我错在哪里?

理想情况下,我想遍历一次源 HashMap keyWordFrequencies,然后将keywordNgrams ArrayList 初始化为开始时可能的最大ngram 大小。

【问题讨论】:

  • 在开始之前,您是否已经知道最大的 ngram-size 是多少?也就是说,你知道keywordNgrams.size()的最终值是多少吗?如果是这样,那么您最好将keywordNgrams 预先填充到该大小;如果没有,那么每当您遇到比以前更大的 ngram 时,您将需要一个循环来将 keywordNgrams 扩展到所需的大小。
  • 是的,我知道这一点。一个 ngram 的最大长度应该是 5。
  • keywordNgrams.add(ngramLength, m); 将不起作用,因为mMap.Entry 实例,而不是HashMap 的实例。您确定要ArrayList&lt;HashMap&gt; 而不是ArrayList&lt;Map.Entry&gt;?使用ArrayList&lt;HashMap&gt;,您将创建一个包含 5 个元素的列表,每个元素都是完全相同的 HashMap,我怀疑这是您想要的。
  • 然后通过m本身访问key和value?听起来很有希望。
  • 感谢受访者:我会在早上试试这些看看。

标签: java arraylist hashmap


【解决方案1】:

由于您正在处理大小为 5 的 ArrayList,因此我建议您在初始化 ArrayList 时,通过在每个索引处添加一个新的 HashMap 实例来执行此操作。像这样的:

ArrayList<HashMap<String, Integer>> keywordNgrams = new ArrayList<HashMap<String, Integer>> ();

for(int index = 0; index < 5; index++){
  keywordNgrams .put(index, new HashMap<String, Integer>());
}

要在 ArrayList 中添加元素,您需要执行以下操作:

  • 访问指定'n'-gram 的特定HashMap。您可以在 ArrayList 上使用 get(int index) 来做到这一点
  • 然后您将添加您返回的 HashMap 的元素,然后再次对您的 keywordNgrams ArrayList 执行同一 HashMap 的set(int index, E element)

示例代码可能是这样的:

HashMap<String, Integer> returnedMap = keywordNgrams.get(index); //where index is the position in the list;
returnedMap.put(key, value); //where key & value is the information that you would want to add to your HashMap
keywordNgrams.set(index, returnedMap);

【讨论】:

    【解决方案2】:

    由于您知道最大的 ngram-size,我建议预先填充 keywordNgrams

    List<Map<String, Integer>> keywordNgrams =
        new ArrayList<Map<String, Integer>>();
    for(int i = 0; i < 5; ++i)
        keywordNgrams.add(new HashMap<String, Integer>());
    

    然后你可以写:

    for(final String keyword : keyWordFrequencies.keySet())
        keywordNgrams.get(String_Utils.getLengthOfNgram(keyword) - 1)
                .put(keyword, keyWordFrequencies.get(keyword));
    

    【讨论】:

    • 这将使用正确的 ngrams 填充目标关键字 Ngrams HashMaps,但没有来自源 keyWordFrequencies 的频率。但是通过删除 if...else : map.put(key.toString(), ((Integer) keywordFrequencies.get(key.toString())).intValue());似乎没问题。非常感谢。
    • @MrMorgan:啊,我明白了。我不明白为什么你的原始地图是从StringInteger,但我现在明白了。我会相应地更新我的答案。
    • @MrMorgan:我已经更新了我的答案。如您所见,您不需要使用key.toString(),也不需要强制转换为Integer,只要您保留开头的类型:因为keyWordFrequencies 具有HashMap&lt;String, Integer&gt; 类型,转换应该已经由编译器为你处理好了。
    • FAO ruakh:我已经尝试过您修改过的代码,它看起来运行良好。为了稍微澄清一下,我需要使用专门的目标 HashMaps 来记录每个 ngram 在原始 HashMaps 中出现的次数,即keywordNgrams(0) 存储一元组,keywordNgrams(1) 存储二元组及其频率,keywordNgrams(2)将存储三元组等。我想另一种选择是让一个非常长的目标 HashMap 将所有 uni、bi 和 trigram 存储在一起,但这可能不太灵活。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多