0

i discovered a strange behavior in HashMap using Eclipse 4.7.2.

The following line seems correct for me:

infos.containsKey("desc") ? stmt.setString(8, infos.get("desc")) : 
stmt.setString(8, "No description");

infos is type of HashMap<String, String> and a PreparedStatement should be filled with the value of the description (desc) field in the map.

But instead of just doing what is written there Eclipse indicates that in this line are multiple errors:

 infos.containsKey**("desc")** ? stmt.setString(8, infos.get("desc")) :
 stmt.setString(8, "No description"**)**;

I marked the characters which are underlined in Eclipse.

The error message is:

Multiple markers at this line
    - Syntax error on token ")", delete this token
    - Syntax error, insert ")" to complete Expression
    - Type mismatch: cannot convert from String to 
     boolean

The function of the ? operater is rather clear but the behavior is unclear.

Does anyone can show me where I am wrong or how to aviod this error.

Thank you!

Tobias Schäfer
  • 1,330
  • 2
  • 17
  • 35
  • 1
    Why not `stmt.setString(8, infos.containsKey("desc") ? infos.get("desc") : "No description");`? – EpicPandaForce Jan 12 '18 at 15:02
  • @EpicPandaForce thank you, in my comment I did it the same way :-D – Tobias Schäfer Jan 12 '18 at 15:03
  • The difference is that your latter ternary "returns" a string that's not assigned to any variable but which _could_ be assigned. Your original version would "return" `void` which can not be assigned and hence isn't supported. From the [JLS](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25): `It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.` – Thomas Jan 12 '18 at 15:03
  • 1
    [Can Java's ternary/conditional operator (?:) be used to call methods instead of assigning values?](https://stackoverflow.com/q/12554547) – Bernhard Barker Jan 12 '18 at 15:15

4 Answers4

5

Problem is that conditional operator boolean ? value1 : value2 expects values but stmt.setString returns void which represents lack of any value.

Simpler solution would be using Map#getOrDefault(key, defaultValue) provided in Java 8 like

stmt.setString(8, infos.getOrDefault("desc", "No description"));
Pshemo
  • 122,468
  • 25
  • 185
  • 269
1

The PreparedStatement.setString method returns void.

The purpose of the ternary operator is to return one value or another. Therefore, you cannot use expressions returning void. Furthermore, both expressions must return a value of the same type.

As indicated elsewhere, you should use a traditional if ... else statement, or write it like this:

stmt.setString(8, infos.containsKey("desc") ? infos.get("desc") : "No description")
rghome
  • 8,529
  • 8
  • 43
  • 62
0

Convert your code to traditional if...else instead of ternary operator

if(infos.containsKey("desc"))
   stmt.setString(8, infos.get("desc"));
else
   stmt.setString(8, "No description");
Vasily Liaskovsky
  • 2,248
  • 1
  • 17
  • 32
0

It is a compile-time error in ternary operator for either the second or the third operand expression to be an invocation of a void method. More you can read about it here

java conditional operator

you can use like this.

 String str = infos.containsKey("desc") ?  infos.get("desc") : "No description";
 stmt.setString(8, str);
rghome
  • 8,529
  • 8
  • 43
  • 62
Anuj jain
  • 493
  • 1
  • 8
  • 26