Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Incompatible types" when accessing Map#entrySet()

I am working on a simple config file reader for fun, but I am getting an odd error while writing the test method. In it is a for loop, and I have made sure that it causes the problem. It gives me this compilation error:

Incompatible types:
    Required: java.util.Map.Entry
    Found: java.lang.Object

The Map declaration is this:

Map<String, String> props = new HashMap<String, String>();

The for loop is written as below:

for (Map.Entry<String, String> entry : props.entrySet()) {
    //Body
}

An SSCCE without imports which demonstrates the problem (At least in IntelliJ):

public class A {
    public static void main(String[] args) {
        Map<String, String> props = new HashMap<String, String>();
        for (int i = 0; i < 100; i++) {
            props.put(new BigInteger(130, random).toString(32), new BigInteger(130, random).toString(32));
        }
        for (Map.Entry<String, String> entry : props.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }
}

map is a Map<String, String>, so that can't be the problem. I have googled alternative methods of doing this, but the main one people use seems to be this one! Yet for some reason it still fails. Any help would be appreciated. If you offer an alternative solution, please make sure it is fast - these config files could potentially be huge.

like image 644
Nic Avatar asked Nov 21 '13 14:11

Nic


1 Answers

Here's a demonstration of what you may be doing - it is difficult to be sure without more code.

class ATest<T> {
  Map<String, String> props = new HashMap<String, String>();

  void aTest() {
    // Works fine.
    for (Map.Entry<String, String> entry : props.entrySet()) {
    }
  }

  void bTest() {
    ATest aTest = new ATest();
    // ERROR! incompatible types: Object cannot be converted to Entry<String,String>
    for (Map.Entry<String, String> entry : aTest.props.entrySet()) {
    }
  }

  void cTest(Map props) {
    // ERROR! incompatible types: Object cannot be converted to Entry<String,String>
    for (Map.Entry<String, String> entry : props.entrySet()) {
    }
  }

}

Notice that in bTest I create an ATest without its generic type parameter. In that situation Java removes all generic information from the class, including, as you will see, the <String,String> from the props variable inside it.

Alternatively - you may be accidentally removing the generic nature of the properties map - like I demonstrate in cTest.

like image 68
OldCurmudgeon Avatar answered Oct 20 '22 14:10

OldCurmudgeon