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

8

我已经设置了一个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类如何工作:/问题在于我没有“值”...名称...对于HashMap可用的'sAccuser's...

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

谢谢。


1
+1 哎呀!这么多答案,但是没有一个回答者觉得给问题点个赞吗?点赞意味着问题写得好,具体明确,并且展示了用户已经尝试过的内容。这个问题满足所有点赞的要求。 - Jim Garrison
@Jim... :) 谢谢!哇...终于有人这样认可我,感觉真好。非常感谢你...希望还有更多的人像你这样想 :) 谢谢!+1指定我的问题符合所有升级的要求。 - Hristo
@Jim Garrison,您说得对。但对我而言,还有两个要求——问题应该难一些,并且具有共同的兴趣——即当你遇到这个问题时,谷歌搜索应该能够导向这个问题。 - Bozho
1
@Bozho... 我会记住你对高质量问题的看法。我认为这是一个难题,因为我以前从未处理过,但你是对的...我可能应该先谷歌一下。我只是觉得如果我在SO上问,我会更快地得到一个确切的答案。至于共同兴趣...那不仅取决于SO社区吗?如果你不感兴趣,其他人可能会感兴趣(希望如此)。谢谢你的意见 :) - Hristo
@Bozho:你说得没错,但我会对新的SO用户放宽这些要求。此外,有很多糟糕和平庸的问题,我会尽可能地给予积极的反馈,以鼓励好的问题。我只是惊讶于这么多人花时间回答却没有点赞。 - Jim Garrison
显示剩余2条评论
6个回答

5
简而言之,我想遍历HashMap并检查特定名称是否存储在任何列表中。那么我该如何做?
这里有两种遍历Map的方法可能会有所帮助。首先,您可以使用entrySet()方法遍历所有映射(即键值对关系),这将让您知道每个ArrayList的键是什么。或者,如果您不需要键,则可以通过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循环省略处理迭代器本身,这样您就不必像我在第一个示例中所利用的那样处理它。

哇...感谢您的回复!我有一个问题...当您说Iterater<String> it = ...;时,它是否等同于一个元素,例如在我的情况下,它是否等同于Set中的一个元素?感谢您提供“for-each”的链接。我从未使用过。非常棒的答案! - Hristo
另外,如果我们回到你的for循环...如果我找到了匹配项,如何提取包含“sAccuser”的ArrayList的名称(键)? - Hristo
1
@Hristo - it 变量将是一个对象,每次调用其 next() 方法时都会返回基础集合的连续元素,而不是元素本身。至于你的第二个问题,我已经修改了我的示例,使用 entrySet() 来迭代 Map,因为这是在关心键和值时迭代 Map 的方式。 - Andrzej Doyle

3

类似这样的内容吗?

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

2
这应该可以让它正常工作:
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
@Hristo 你获得了一个 ArrayList,但是你使用它的接口 List 进行引用,这被认为是一种更好的实践方式(除非你真正需要 ArrayList 指定的方法)。 - Bozho
2
如果您需要键和值,请使用entrySet,而不是keySet和get。 - ILMTitan
哦,有趣……我不知道那个。谢谢! - Hristo

0

你需要使用Iterator.next()返回的值来索引Map

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

目前您正在根据迭代器而非迭代器返回的值从Map中获取值。


0
创建一个方法来实现它:
 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<String> iterAccusers = ...;时,iterAccusers是否等于一个元素,在我这种情况下,它是否等于来自Set的一个元素,或者它是否未初始化? - Hristo
还有一个问题...如果我找到了匹配项,如何提取包含'sAccuser'的ArrayList的名称(键)? - Hristo
iterAccusers是一个迭代器,你可以调用next()方法来获取下一个元素。它就像一个for-each循环一样。这个迭代器不是集合中的元素,而是用于遍历集合的对象。至于提取键值,不要返回列表,只需返回键即可。请参考修改后的代码。 - Jes

0

听起来你需要做两件事情:首先,找出一个给定的名字是否被“指控”,其次,找出控告者是谁。为此,你需要遍历你的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 对象?我还没有遇到过。 - Hristo
它实际上是Map的内部类。完整的类名是java.util.Map.Entry。(JavaDoc在这里:http://download.oracle.com/javase/1.5.0/docs/api/java/util/Map.Entry.html)根据我的经验,它很少被使用。然而,在这种情况下,它非常适用,并且由于它是Map API的一部分,没有理由不使用它。 - DeathB4Decaf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接