如何为每个哈希图?[复制]

How to for each the hashmap? [duplicate]

提问人:Mediator 提问时间:11/21/2010 最后编辑:JarvisMediator 更新时间:12/23/2018 访问量:924500

问:

我有这个字段:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();

对于每个,我都需要创建一个 ,其项目是 的值(恰好是 HashMap 本身)。Hash<String, HashMap>ComboBoxHashMap <String, **HashMap**>

通过(非功能)演示:

for (int i=0; i < selects.size(); i++) {
    HashMap h = selects[i].getValue();
    ComboBox cb = new ComboBox();

    for (int y=0; y < h.size(); i++) {
        cb.items.add(h[y].getValue);
    }
}
爪哇岛

评论

3赞 Nitin Mahesh 7/26/2015
在使用 Lambda 的 Java 8 中: stackoverflow.com/a/25616206/1503859
0赞 akhil_mittal 9/27/2018
Java 8 使用流:stackoverflow.com/a/32343195/1216775,流的一个优点是它们也可以并行化。

答:

9赞 icyrock.com 11/21/2010 #1

entrySet

/**
 *Output: 
D: 99.22
A: 3434.34
C: 1378.0
B: 123.22
E: -19.08

B's new balance: 1123.22
 */

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MainClass {
  public static void main(String args[]) {

    HashMap<String, Double> hm = new HashMap<String, Double>();

    hm.put("A", new Double(3434.34));
    hm.put("B", new Double(123.22));
    hm.put("C", new Double(1378.00));
    hm.put("D", new Double(99.22));
    hm.put("E", new Double(-19.08));

    Set<Map.Entry<String, Double>> set = hm.entrySet();

    for (Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }

    System.out.println();

    double balance = hm.get("B");
    hm.put("B", balance + 1000);

    System.out.println("B's new balance: " + hm.get("B"));
  }
}

在此处查看完整示例:

评论

2赞 icyrock.com 11/21/2010
它绝对有效,我每天都在使用它:)究竟什么不起作用?正如你所拥有的那样,你需要两个循环 - 一个用于外部,一个用于内部 HashMap。顺便说一句 - 你应该明确地输入第二个 HashMap - 不知道你在其中存储了什么,但像 HashMap<String、HashMap<string、String>> 之类的东西 - 虽然,从你的示例来看,你似乎应该使用 .还有一件事 - 使用接口:如果可以的话。HashMap<String, HashMap>HashMap<String, Set<String>>Map<String, Map>
55赞 Bert F 11/21/2010 #2

Map.values():

HashMap<String, HashMap<SomeInnerKeyType, String>> selects =
    new HashMap<String, HashMap<SomeInnerKeyType, String>>();

...

for(HashMap<SomeInnerKeyType, String> h : selects.values())
{
   ComboBox cb = new ComboBox();
   for(String s : h.values())
   {
      cb.items.add(s);
   }
}

评论

2赞 Oliver Charlesworth 11/21/2010
+1:这是一种比我的答案更简洁的方法(假设我们使用的是 Java 5 或更高版本)
1赞 Bert F 11/21/2010
在外部 HashMap 上使用泛型参数似乎表明 Java 5 或更高版本。[[ 但我确实想知道这是什么 Java,因为内部 HashMap 没有通用参数,并且在 HashMap 上完成了数组访问......但它只是一些用于传达问题的“伪”代码。]]
1赞 Bert F 11/21/2010
想解释一下为什么它似乎对你不起作用?您使用的是 Java 5 或更高版本吗?我们正在遵循您的代码示例,该示例在创建组合框后似乎不会对组合框执行任何操作。或者值是否不符合您想要的顺序?或者您是否需要键而不是组合框中的值?我想大多数人都会同意,到目前为止,这 3 个答案中的任何一个都应该可以正常工作,因此很可能存在应用答案的问题或其他地方的问题,如果您向我们提供更多信息,我们可能能够提供帮助。
1赞 Mediator 11/21/2010
噢噢......我傻了=)。只有一个问题如何获取 HashMap<this->String、HashMap<SomeInnerKeyType、String>>
1赞 Bert F 11/21/2010
@simply丹尼斯 - 恐怕我不明白你的问题?你是在问你如何获得参考?如果你的循环在一个方法中,你应该能够使用或简单地使用?否则,应将映射作为参数传递给包含循环的方法。或者你是在问如何获取给定键的特定内部 (?你会用 .如果我完全误解了,请澄清。HashMap<String, HashMap<SomeInnerKeyType, String>>this.selectsselectsHashMap<SomeInnerKeyType, String>this->Stringselects.get(keyString)
23赞 Oliver Charlesworth 11/21/2010 #3

您可以使用迭代器遍历一个(以及许多其他集合),例如:HashMap

HashMap<T,U> map = new HashMap<T,U>();

...

Iterator it = map.values().iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

评论

2赞 Mediator 11/21/2010
我不能用这样的设计下降到下面的水平
3赞 Oliver Charlesworth 11/21/2010
@Yes,你可以。您可以基于 创建内部迭代器。it.next()
1403赞 Cyril N. 1/26/2012 #4

我知道我有点晚了,但我也会分享我所做的事情,以防它对其他人有帮助:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();

for(Map.Entry<String, HashMap> entry : selects.entrySet()) {
    String key = entry.getKey();
    HashMap value = entry.getValue();

    // do what you have to do here
    // In your case, another loop.
}

评论

128赞 Katu 1/23/2015
我从来不记得怎么写这个,所以我总是回到同样的答案。赞成,因为这是干净的答案,并且此代码被复制粘贴到我项目中的许多地方,谢谢!
16赞 AITAALI_ABDERRAHMANE 9/11/2017
@Katu写你的地图......entrySet().for,IDE 自动完成将处理它。
15赞 panahi 6/22/2012 #5

我通常执行与 cx42net 相同的操作,但我没有显式创建 Entry。

HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
for (String key : selects.keySet())
{
    HashMap<innerKey, String> boxHolder = selects.get(key);
    ComboBox cb = new ComboBox();
    for (InnerKey innerKey : boxHolder.keySet())
    {
        cb.items.add(boxHolder.get(innerKey));
    }
}

这对我来说似乎是最直观的,我认为我对迭代地图的值有偏见。

评论

0赞 Azeroth2b 8/27/2022
如果要遍历整个地图,请不要进行查找。每个哈希查找可能是 O(1),但现在当您需要的哈希查找总数为 0 时,您正在为 O(N) 执行其中的 n*O(1)。
295赞 Nitin Mahesh 9/2/2014 #6

Lambda表达式 Java 8

在 Java 1.8 (Java 8) 中,通过使用 Aggregate 操作(Stream 操作)中的 forEach 方法,这变得容易得多,该方法看起来类似于 Iterable Interface 中的迭代器。

只需将以下语句复制粘贴到您的代码中,并将 HashMap 变量从 hm 重命名为 HashMap 变量即可打印出键值对。

HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
 *     Logic to put the Key,Value pair in your HashMap hm
 */

// Print the key value pair in one line.
hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v));

以下是使用 Lambda 表达式的示例:

    HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
    Random rand = new Random(47);
    int i=0;
    while(i<5){
        i++;
        int key = rand.nextInt(20);
        int value = rand.nextInt(50);
        System.out.println("Inserting key: "+key+" Value: "+value);
        Integer imap =hm.put(key,value);
        if( imap == null){
            System.out.println("Inserted");
        }
        else{
            System.out.println("Replaced with "+imap);
        }               
    }

    hm.forEach((k,v) -> System.out.println("key: "+k+" value:"+v));

Output:

Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11

也可以使用 Spliterator 来实现相同的目的。

Spliterator sit = hm.entrySet().spliterator();

更新


包括指向 Oracle Docs 的文档链接。 有关 Lambda 的更多信息,请转到此链接,并且必须阅读聚合操作,对于 Spliterator,请转到此链接

评论

1赞 Mahesha999 12/16/2016
我想我们不能在不声明它们的情况下在封闭范围内使用局部变量。在使用在 lambda 主体外部声明的变量时得到,这与 groovy 中的闭包不同。Local variable schedule defined in an enclosing scope must be final or effectively final
5赞 apscience 3/30/2017
使用 lambda 的缺点是,在 lambda 内部无法返回其他方法。
0赞 akhil_mittal 10/10/2018
分离器在这里有什么用?您是否正在使用并行流?
0赞 A.J. 3/13/2022
如果您使用的是 android,则此处提到的 forEach 调用需要 API 级别 24。
33赞 akhil_mittal 9/2/2015 #7

流 Java 8

除了接受 lambda 表达式的方法外,我们还在 Java 8 中提供了 API。forEach

遍历条目(使用 forEach 和 Streams):

sample.forEach((k,v) -> System.out.println(k + "=" + v)); 
sample.entrySet().stream().forEachOrdered((entry) -> {
            Object currentKey = entry.getKey();
            Object currentValue = entry.getValue();
            System.out.println(currentKey + "=" + currentValue);
        });
sample.entrySet().parallelStream().forEach((entry) -> {
            Object currentKey = entry.getKey();
            Object currentValue = entry.getValue();
            System.out.println(currentKey + "=" + currentValue);
        });

流的优点是它们可以很容易地并行化,当我们有多个 CPU 可供使用时,它们会很有用。我们只需要用 in 代替上面的。使用并行流更有意义,因为不会对性能产生任何影响。如果我们想遍历键,我们可以使用 和 for 值 。parallelStream()stream()forEachforEachOrderedsample.keySet()sample.values()

为什么 forEachOrdered 而不是 forEach 与流?

流也提供方法,但其行为是明确的非确定性的,因为 如果流具有定义的相遇顺序,则在流的相遇顺序中,为此流的每个元素执行操作。所以不保证订单会被保留。另请查看内容以了解更多信息。forEachforEachforEachOrderedforEach