简体   繁体   English

如何在Java中使用foreach循环来遍历HashMap中的值?

[英]How do I use a foreach loop in Java to loop through the values in a HashMap?

I am trying to compile the following code: 我正在尝试编译以下代码:

private String dataToString(){
    Map data = (HashMap<MyClass.Key, String>) getData();
    String toString = "";
    for( MyClass.Key key: data.keySet() ){
        toString += key.toString() + ": " + data.get( key );
    return toString;
}

I get an error in the for line that says: 我在for行中遇到错误:

incompatible types
found : java.lang.Object
required: MyClass.Key

The getData() method returns an Object (but in this case the Object returned has the HashMap structure). getData()方法返回一个Object (但在这种情况下,返回的Object具有HashMap结构)。 MyClass.Key is an enum that I have created for the purposes of my application (in another class file - MyClass ). MyClass.Key是我为我的应用程序创建的枚举(在另一个类文件中 - MyClass )。

When I created a foreach loop with the same structure in MyClass.java , I did not encounter this problem. 当我在MyClass.java创建一个具有相同结构的foreach循环时,我没有遇到这个问题。

What am I doing wrong? 我究竟做错了什么?

A slightly more efficient way to do this: 一种稍微有效的方法:

  Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData(); 
  StringBuffer sb = new StringBuffer();
  for (Map.Entry<MyClass.Key,String> entry : data.entrySet()) {
       sb.append(entry.getKey());
       sb.append(": ");
       sb.append(entry.getValue());
   }
   return sb.toString();

If at all possible, define "getData" so you don't need the cast. 如果可能的话,定义“getData”,这样你就不需要演员了。

Change: 更改:

Map data = (HashMap<MyClass.Key, String>) getData();

to

Map<MyClass.Key, String> data = (HashMap<MyClass.Key, String>) getData();

The problem is that data.keySet() returns a Collection<Object> if data is just a Map . 问题是如果data只是一个Mapdata.keySet()返回一个Collection<Object> Once you make it generic, keySet() will return a Collection<MyClass.Key> . 一旦你使它成为通用的, keySet()将返回Collection<MyClass.Key> Even better... iterate over the entrySet() , which will be a Collection<MyClass.Key, String> . 甚至更好......遍历entrySet() ,它将是Collection<MyClass.Key, String> It avoids the extra hash lookups. 它避免了额外的哈希查找。

I found this simple example at java forum . 我在java论坛上找到了这个简单的例子。 Its syntax is very similar to the List's foreach , which was what I was looking for. 它的语法与List的foreach非常相似 ,这正是我所寻求的。

import java.util.Map.Entry;
HashMap nameAndAges = new HashMap<String, Integer>();
for (Entry<String, Integer> entry : nameAndAges.entrySet()) {
        System.out.println("Name : " + entry.getKey() + " age " + entry.getValue());
}

[EDIT:] I tested it and it works perfectly. [编辑:]我测试了它,它完美地工作。

You could grab the entrySet instead, to avoid needing the key class: 您可以改为使用entrySet,以避免需要密钥类:

private String dataToString(){    
    Map data = (HashMap<MyClass.Key, String>) getData();    
    String toString = "";    
    for( Map.Entry entry: data.entrySet() ) {        
        toString += entry.getKey() + ": " + entry.getValue();
    }    
    return toString;
}

Motlin's answer is correct. 莫特林的回答是正确的。

I have two notes... 我有两个笔记......

  1. Don't use toString += ... , but use StringBuilder instead and append data to it. 不要使用toString += ... ,而是使用StringBuilder并将数据附加到它。

  2. Cast which Martin suggested will give you unchecked warning, which you won't be able to get rid of, because it is really unsafe. 马丁建议的演员会给你一个未经检查的警告,你将无法摆脱它,因为它真的不安全。

Another way, without warning (and with StringBuilder): 另一种方式,没有警告(和StringBuilder):

private String dataToString(){
    Map<?, ?> data = (Map<?, ?>) getData();
    StringBuilder toString = new StringBuilder();
    for (Object key: data.keySet()) {
        toString.append(key.toString());
        toString.append(": ");
        toString.append(data.get(key));
    }
    return toString.toString();
}

This works, because toString method which you call on key is defined in Object class, so you don't need casting at all. 这是有效的,因为您在key上调用的toString方法是在Object类中定义的,因此您根本不需要进行转换。

Using entrySet is even better way, as it doesn't need to do another look-up in map. 使用entrySet是更好的方法,因为它不需要在map中进行另一次查找。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM