QPaysTaxes QPaysTaxes - 5 months ago 24
Java Question

"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.

Answer

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.