如何从 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();
...但是我不确定Set
和Iterator
类是如何工作的:/ 问题是我没有“值”...名称...'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);
目前,您基于 iterator 从 Map
获取值,而不是迭代器返回的值。
【讨论】:
【参考方案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<String> 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<String> 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 中获取不同的值