Ternary operator with string concatination causes partial loss of content? - java

Boolean isValid = true;
String message = "prefix" + isValid != null ? " midfix " : "suffix";
System.out.println(message);
What do you think is the result of this? I'd expect prefix midfix. But actually the result is: midfix!
Is this an error in the java library itself (1.7)? Should I report a bug for this? Or does this work as intended, and I'm misusing it?
It can be "fixed" using:
String message = "prefix" + (isValid != null ? " midfix " : "suffix");
but anyways shouldn't it work without the brakets?

It is evaluated as :
String message = (("prefix" + isValid) != null) ? " midfix " : "suffix";
which is equivalent to :
String message = ("prefixtrue" != null) ? " midfix " : "suffix";
Therefore "midfix" is returned.
If you wish "prefix midfix" to be returned use parentheses:
String message = "prefix" + (isValid != null ? " midfix " : "suffix");

Related

Filter with addition or subtraction condition

I have a simple json payload. I would like to add a filter condition on this which checks if (mode == 'custom' and lastUpdatedDate - createdDate >= 180000).
Can someone help with the filter condition.
{
"id":"1664437560",
"mode":"CUSTOM",
"createdDate":1664437561000,
"lastUpdatedDate":1664437620256,
"customerIdentifier":"8a9fcc828",
"status":"Success"
}
p.s -- I am familiar with jsonpath but, could not find a way to have a filter condition with +/-/* operators. I also tried to add filter condition on sum function,which also didn't work.
Library Josson can do the job.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"{" +
" \"id\":\"1664437560\"," +
" \"mode\":\"CUSTOM\"," +
" \"createdDate\":1664437561000," +
" \"lastUpdatedDate\":1664437620256," +
" \"customerIdentifier\":\"8a9fcc828\"," +
" \"status\":\"Success\"" +
"}");
Query
JsonNode node = josson.getNode("[mode='CUSTOM' & calc(lastUpdatedDate - createdDate) >= 180000]");
System.out.println(node == null ? null : node.toPrettyString());
Output
null
Deserialization (Changed lastUpdatedDate to 1664437861000)
Josson josson = Josson.fromJsonString(
"{" +
" \"id\":\"1664437560\"," +
" \"mode\":\"CUSTOM\"," +
" \"createdDate\":1664437561000," +
" \"lastUpdatedDate\":1664437861000," +
" \"customerIdentifier\":\"8a9fcc828\"," +
" \"status\":\"Success\"" +
"}");
Query
JsonNode node = josson.getNode("[mode='CUSTOM' & calc(lastUpdatedDate - createdDate) >= 180000]");
System.out.println(node == null ? null : node.toPrettyString());
Output
{
"id" : "1664437560",
"mode" : "CUSTOM",
"createdDate" : 1664437561000,
"lastUpdatedDate" : 1664437861000,
"customerIdentifier" : "8a9fcc828",
"status" : "Success"
}

How make getRequestURI and queryString in jsp

I am using this:
<li ${(requestScope['javax.servlet.forward.request_uri']=='/example') ? "class='active';" : ""}>
And this code activates my link to me but I've written such code to be active: ${(requestScope['javax.servlet.forward.request_uri'] +="?"+ requestScope['javax.servlet.forward.query_string']=='/example/?buy=e') ? "class='active';" : ""}
But I am getting an error.
Can I get your solution suggestions?
Try this below.
String uri = request.getScheme() + "://" +
request.getServerName() +
("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) +
request.getRequestURI() +
(request.getQueryString() != null ? "?" + request.getQueryString() : "");
Note:
This snippet above will get the full URI, hiding the port if the default one was used, and not adding the "?" and the query string if the latter was not provided.

Ternary operator for strings - any nicer way?

I'm concerned about this construct:
String out = "Text " + (obj==null ? "" : obj.getStr()+" ") + "text continues.";
It works and all, but I think it's ugly. Maybe I'm just too picky..
Anyway, I'm asking, is there some nicer way to do this kind of stuff?Or is this the generally accepted technique?
Use a StringBuilder:
final StringBuilder sb = new StringBuilder("Text ");
if (obj != null)
sb.append(obj.getStr()).append(' ');
final String out = sb.append("text continues.").toString();
Also, why .getStr()? Doesn't obj implement .toString()?
Note that if obj did implement .toString(), you could do "better" than that using Guava's Joiner:
private static final Joiner JOINER = Joiner.on(" ").skipNulls();
//
final String out = JOINER.join("Text", obj, "text continues.");
Ultimately, though, that is a question of style.
Well you can separate out the logic from the format, to start with:
String out = String.format("Text %stextcontinues",
obj == null ? "" : obj.getStr() + " ");
I like it better because it is concise.
The other way is the plain old if-then-else:
String toAdd = "";
if(object != null) {
obj.getStr() + " ";
}
String out = "Text " + toAdd + "text continues.";
String out = "Text text continues.";
if (obj != null)
out = "Text " + obj.getStr() + " text continues.";

printing statement with operator ? : causes unexpected output

I had to create an output depending on an boolean state like
String smily = null;
StringBuffer buff = new StringBuffer();
buff.append(", " + smily == null ? ":)" : ":("); //$NON-NLS-1$
System.out.println(buff.toString());
The problem is the String creation statement
", " + smily == null ? ":)" : ":("
I tested it in 2 different eclipse environments (and may be also 2 diofferent java version, this i did not checked) and the result was different.
Result 1:
:(
Result 2:
false:(
Of course, if i added brackets it is working
buff.append(", " + (smily == null ? ":)" : ":(")); //$NON-NLS-1$
Expected Result:
, :)
Can please somebody explain to me, why java interprets the statement that way?
Thanks
If you check the operator precedence (see this tutorial), then you will notice that addition (+) comes before equality (==). In other words, Java will first evaluate ", " + smily => ", null" before evaluating equality, therefor ", " + smily == null evaluates to false, and so the ternary operator evaluates to ":(".
BTW: You could have avoided this by not concatenating strings before adding them to the StringBuffer (the whole point of a StringBuffer is to make concatenation cheaper):
String smily = null;
StringBuffer buff = new StringBuffer();
buff.append(", ");
buff.append(smily == null ? ":)" : ":(");
the expression ", " + smily == null ? ":)" : ":(" is evaluated as (", " + smily) == null ? ":)" : ":("
This explains your result 1. To be honest, I don't know why result 2 was possible.
StringBuffer.append() takes a String parameter. So when you put this without brackets
buff.append(", " + smily == null ? ":)" : ":(")
at the time of evaluation will be ", " + null. So when the evaluation happens it is always false.
As for why the same code returned two results I can only assume that two different Java versions were used and they handled this situation differently.
String smily = null;
StringBuffer buff = new StringBuffer();
if(smily == null){
buff.append(", " + ":)") ; //$NON-NLS-1$
}else{
buff.append(", " + ":(") ; //$NON-NLS-1$
}
Try this.....................
buff.append(", " + smily == null ? ":)" : ":(");
- In the above statement you are Not mentioning the smily == null ? ":)" : ":(" to be evaluated in the proper way it has to be.
- To solve this you have to use BODMAS rule, the below are always evaluated in the way it has been listed from Left to Right.
Bracket
Power
Division and Multiplication
Addition and Substraction
- Use Bracket to enclose the smily == null ? ":)" : ":("
Eg:
public class Test {
public static void main(String[] args){
String smily = null;
StringBuffer buff = new StringBuffer();
buff.append(", " + (smily == null ? ":)" : ":(")); //$NON-NLS-1$
System.out.println(buff.toString());
}
}
Output: , :)

Why does this throw NullPointerException?

e.getCategory() != null ? e.getCategory().getName() : "";
This throws a NullPointerException and I do not understand why. Can anyone explain?
Explanation:
According to Java's precedence rules, your code was being parsed like this:
(("\"category\":" + "\"" + e.getCategory()) != null) ? e.getCategory().getName() : ""
with the entire concatenation (("..." + e.getCategory())!= null) as the condition.
Since "..." + e.getCategory() is never null, the code didn't work.
e is null.
Is e null?
Perhaps you should try this:
(e != null) ?
(e.getCategory() != null) ?
e.getCategory().getName() :
""
: ""
Or rather, a simplified form:
(e != null && e.getCategory() != null) ?
e.getCategory().getName() :
""
Solution found....
CORRECT
bufo.append("\"category\":" + "\"" + ((e.getCategory() != null) ? e.getCategory().getName() : "") + "\",");
PROBLEM
bufo.append("\"category\":" + "\"" + e.getCategory()!=null?e.getCategory().getName():"" + "\",");

Categories