如何从 HashMap 中提取 ArrayList 并在 Java 中循环遍历它?

Posted

技术标签:

【中文标题】如何从 HashMap 中提取 ArrayList 并在 Java 中循环遍历它?【英文标题】:How can I extract ArrayList from HashMap and loop through it in Java? 【发布时间】:2011-03-27 13:08:32 【问题描述】:

我已经像这样设置了一个 HashMap:

Map<String, ArrayList<String>> theAccused = new HashMap<String, ArrayList<String>>();

...我通过为每个名称(键)存储一个名称列表(值)来填充它。所以:

ArrayList<String> saAccused = new ArrayList<String>();
// populate 'saAccused' ArrayList
...
// done populating
theAccused.put(sAccuser, saAccused);

所以现在,我想查看 HashMap 中的所有条目,看看(对于每个 'sAccuser'),列表 'saAccused' 是否包含某个名称。到目前为止,这是我失败的尝试:

Set<String> setAccusers = theAccused.keySet();
Iterator<String> iterAccusers = setAccusers.iterator();
iterAccusers.next();
ArrayList<String> saTheAccused;

// check if 'sAccuser' has been accused by anyone before
for (int i = 0; i < theAccused.size(); i++) 
    saTheAccused = theAccused.get(iterAccusers);

    if (saTheAccused.contains(sAccuser)) 

    
    iterAccusers.next();

...但是我不确定SetIterator 类是如何工作的:/ 问题是我没有“值”...名称...'sAccuser' s... 对于可用的 HashMap。

简而言之,我想遍历 HashMap 并检查特定名称是否存储在任何列表中。那么我该怎么做呢?如果您需要我进一步详细说明或澄清任何困惑,请告诉我。

谢谢。

【问题讨论】:

+1 嘘!一堆答案,但没有一个回答者愿意为这个问题投票?赞成票意味着问题写得很好,具体,并显示了用户已经尝试过的内容。此问题符合投票的所有要求。 @Jim... :) 谢谢!哇……终于有人以这种方式认出我的感觉真好。非常感谢...我希望更多的人像你一样思考:) 谢谢! +1 表示我的问题符合投票的所有要求。 @Jim Garrison 你是对的,但对我来说还有两个要求 - 这个问题应该是困难的,并且是共同感兴趣的 - 即当你遇到问题时,谷歌搜索应该导致这个问题。 @Bozho... 我会记住您对质量问题的看法。我认为这是一个很难的问题,因为我以前从未处理过这个问题,但你是对的......我可能可以先用谷歌搜索它。我只是觉得如果我问的话我会更快地得到一个准确的答案。就共同利益而言……这不只取决于 SO 社区吗?如果你不感兴趣,其他人会(希望如此)。感谢您的意见:) @Bozho:你说得对,但我放宽了对新 SO 用户的要求。另外,有很多糟糕和平庸的问题,我会在适当的时候尝试给出积极的反馈,以鼓励提出好的问题。我很惊讶有这么多人花时间回答而没有投票。 【参考方案1】:

您需要使用来自Iterator.next() 的值来索引Map

String key = iterAccusers.next();
saTheAccused = theAccused.get(key);

目前,您基于 iteratorMap 获取值,而不是迭代器返回的值。

【讨论】:

【参考方案2】:

这样的?

for (List<String> list : theAccused.values()) 
    if (list.contains("somename")) 
        // found somename
    

【讨论】:

【参考方案3】:

这应该使它工作:

saTheAccused = theAccused.get(iterAccused.next());

但是,为了使您的代码更具可读性,您可以:

for (List<String> values : theAccused.values()) 
    if (value.contains(sAcuser)) 
       ..
    

或者,如果您需要密钥:

for (String key : theAccused.keySet()) 
    List<String> accused = theAccused.get(key);
    if (accused.contains(sAccuser)) 
    

【讨论】:

谢谢。这就是我需要的。不过请修改您的答案...我正在寻找一个 ArrayList...我不希望您因为愚蠢的原因而被否决:) @Hristo 你得到一个ArrayList,但你通过它的接口引用它 - List,这被认为是一种更好的做法(除非你真的需要ArrayList 特定的方法)跨度> 如果你需要key和value,你应该使用entrySet,而不是keySet和get。 .. 哦,有趣...我没有意识到这一点。谢谢!【参考方案4】:

简而言之,我想遍历 HashMap 并检查特定名称是否存储在任何列表中。那么我该怎么做呢?

这里有两种迭代地图的方法可能会让人感兴趣。首先,您可以使用 entrySet() 方法遍历所有映射(即键值关系对),这将使您知道每个数组列表的键是什么。或者,如果您不需要密钥,您可以简单地通过values() 方法依次获取所有列表。使用第一个选项可能看起来像这样:

for (Map.Entry<String, ArrayList<String>> entry : theAccused.entrySet())

   String sListName = entry.getKey();
   ArrayList<String> saAccused = entry.getValue();
   if (saAccused.contains(sAccuser))
   
      // Fire your logic for when you find a match, which can
      // depend on the list's key (name) as well
   

要回答更广泛的问题 - Set 接口仅表示非重复值的(无序)集合。正如您从链接的 Javadoc 中看到的那样,对于此类无序集合,您可能期望有一些可用的方法。 Iterator 是一个对象,它遍历一些依次呈现每个元素的数据结构。迭代器的典型用法如下所示:

Iterator<?> it = ...; // get the iterator somehow; often by calling iterator() on a Collection
while (it.hasNext())

   Object obj = it.next();
   // Do something with the obj

即检查迭代器是否未用尽(有更多元素)然后调用next() 方法获取该元素。但是,由于上述模式非常常见,因此可以使用 Java 5 的 foreach loop 将其省略,从而使您无需处理迭代器本身,正如我在第一个示例中所利用的那样。

【讨论】:

哇...感谢您的回复!快速提问...当您说Iterater&lt;String&gt; it = ...; 时,它是否等于一个元素,在我的情况下,它是否等于集合中的一个元素?感谢“for-each”的链接。我从来没有使用过它。出色的答案! 另外...如果我们回到您的 for 循环...如果我找到匹配项,我如何提取包含 'sAccuser' 的 ArrayList 的名称(键)?跨度> @Hristo - it 变量将是一个对象,每次调用其next() 方法时都会返回底层集合的连续元素,而不是元素本身。至于您的第二个问题,我已经修改了我的示例以使用entrySet() 显示它,因为这是在您关心 键值时迭代 Map 的方式。【参考方案5】:

创建一个方法:

 private String findListWithKeyword(Map<String, ArrayList<String>> map, String keyword) 
   Iterator<String> iterAccusers = map.keySet().iterator();
   while(iterAccusers.hasNext()) 
      String key = iterAccusers.next();
      ArrayList<String> list = theAccused.get(key);
      if (list.contains(keyword)) 
         return key;
       
   

当你调用方法时:

String key = findListWithKeyword(map, "foobar");
ArrayList<String> theCorrectList = map.get(key);

【讨论】:

.. 感谢您的回复。我已经在编写一个这样做的方法。这是我的问题的重点:) 快速问题...当您说Iterater&lt;String&gt; iterAccusers = ...; 时,iterAccusers 是否等于一个元素,在我的情况下,它是否等于 Set 中的一个元素,还是一开始就未初始化? 另外,还有一个问题......如果我确实找到了匹配项,如何提取包含它所属的“sAccuser”的 ArrayList 的名称(键)? iterAccusers 是一个迭代器,即您可以在其上调用 next() 并获取下一个元素。这就像一个 for-each 循环。迭代器不是集合中的元素,它是用于迭代集合的对象。至于提取密钥。无需返回列表,只需返回键即可。查看修改后的代码。【参考方案6】:

听起来您需要做两件事:首先,找出给定名称是否“被指控”,其次,找出指控者是谁。为此,您需要遍历 Map 中的 Entry 对象。

    for (Entry<String, List<String>> entry : theAccused.entrySet()) 
        if (entry.getValue().contains(accused)) 
            return entry.getKey();
        
    

    return null; // Or throw NullPointerException, or whatever.

在这个循环中,Entry 对象拥有一个键值映射。所以 entry.getValue() 包含被告名单,entry.getKey() 包含他们的原告。

【讨论】:

.. 什么是 Entry 对象?我还没有遇到过。 其实是 Map 的一个内部类。完整的类名是 java.util.Map.Entry。 (JavaDoc 在这里:download.oracle.com/javase/1.5.0/docs/api/java/util/…)根据我的经验,它很少使用。但是,在这种情况下,它可以很好地发挥作用,并且由于它是 Map API 的一部分,因此没有理由不使用它。

以上是关于如何从 HashMap 中提取 ArrayList 并在 Java 中循环遍历它?的主要内容,如果未能解决你的问题,请参考以下文章

java.util.HashMap 不能转换为 java.util.ArrayList

如何从 ArrayList<HashMap<String, String>> android 中获取所有元素

Java ArrayList:从包含 HashMap 的 ArrayList 中获取不同的值

从Hashmap的所有值中获取所有嵌套项

从源码角度认识 ArrayList ,LinkedList与 HashMap

从 ArrayList Java 中的 HashMap 键中检索所有值