【问题标题】:How can I extract ArrayList from HashMap and loop through it in Java?如何从 HashMap 中提取 ArrayList 并在 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 用户的要求。另外,有很多糟糕和平庸的问题,我会在适当的时候尝试给出积极的反馈,以鼓励提出好的问题。我很惊讶有这么多人花时间回答而没有投票。

标签: java arraylist hashmap lookup contains


【解决方案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 的一部分,因此没有理由不使用它。
      猜你喜欢
      • 2015-12-26
      • 2017-06-21
      • 2010-12-22
      • 2015-02-13
      • 2011-10-08
      • 1970-01-01
      • 2013-01-09
      • 1970-01-01
      相关资源
      最近更新 更多