I want to get string values of my fields (they can be type of long string or any object),
if a field is null then it should return empty string, I did this with guava;
nullToEmpty(String.valueOf(gearBox))
nullToEmpty(String.valueOf(id))
...
But this returns null if gearbox is null! Not empty string because valueOf methdod returns string "null" which leads to errors.
Any Ideas?
EDIt: there are 100s fields I look for something easy to implement
You can use Objects.toString() (standard in Java 7):
Objects.toString(gearBox, "")
Objects.toString(id, "")
From the linked documentation:
public static String toString(Object o, String nullDefault)
Returns the result of calling toString on the first argument if the first argument is not null and returns the second argument otherwise.
Parameters:
o - an object
nullDefault - string to return if the first argument is null
Returns:
the result of calling toString on the first argument if it is not null and the second argument otherwise.
See Also:
toString(Object)
For java 8 you can use Optional approach:
Optional.ofNullable(gearBox).orElse("");
Optional.ofNullable(id).orElse("");
If you don't mind using Apache commons, they have a StringUtils.defaultString(String str) that does this.
Returns either the passed in String, or if the String is null, an empty String ("").
If you also want to get rid of "null", you can do:
StringUtils.defaultString(str).replaceAll("^null$", "")
or to ignore case:
StringUtils.defaultString(str).replaceAll("^(?i)null$", "")
If alternative way, Guava provides Strings.nullToEmpty(String).
Source code
String str = null;
str = Strings.nullToEmpty(str);
System.out.println("String length : " + str.length());
Result
0
Use an inline null check
gearBox == null ? "" : String.valueOf(gearBox);
StringUtils.defaultString(String str) Returns either the passed in String, or if the String is null, an empty String ("").
Example from java doc
StringUtils.defaultString(null) will return ""
StringUtils.defaultString("") will return ""
StringUtils.defaultString("bat") will return "bat"
Since you're using guava:
Objects.firstNonNull(gearBox, "").toString();
In Java 9+ use : Objects.requireNonNullElse (obj, defaultObj) https://docs.oracle.com/javase/9/docs/api/java/util/Objects.html#requireNonNullElse-T-T-
//-- returns empty string if obj is null
Objects.requireNonNullElse (obj, "")
Related
Is there any utility available to easily get the string representation of an arbitrary object if it exists and keep it null if it was null?
For example
String result = null;
if (object != null) {
result = object.toString();
}
but less verbose.
I have looked into ObjectUtils and String.valueOf but neither returns just null itself. Both return default strings, i.e. the empty string or the string "null" instead of just null.
If I understand your problem, you can use that (java.util.Objects is here since JDK7):
Objects.toString(s, null); // return null if s is null, s.toString() otherwise
In fact, it works for every object.
Imagine an Optional.ofNullable check assigning to a String:
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult);
Where getResult returns a String.
While I know this doesn't compile, I can fix it by either adding toString() or .orElse(""); to sort that.
As it stands, the error is:
Bad return type in method reference, cannot convert java.lang.String
to U
I understand adding orElse("") as that will assign result to an empty String.
But what's the benefit of adding toString() if something is null along the way? Or is that just to purely get it to compile?
The return type of map is Optional <U>, so to get a real value you should call for orElse with the return type of T.
This is the toString implementation if the Optional:
#Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
So, calling toString you'll never get the real value, but a value wrapped to Optional, while orElse will return you the default provided value.
Let's see the difference:
Integer i = 4;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional[4]
With null:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional.empty
While using orElse:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
None
So you can see that there are different purposes of these methods.
And the answer to your comment:
"Is there a way to call get() and also call orElse() in the same chain?"
Integer i = 10;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
10
You don't need to call get explicitly, the value will be fetched if not null;
/**
* If a value is present, returns the value, otherwise returns
* {#code other}.
*
* #param other the value to be returned, if no value is present.
* May be {#code null}.
* #return the value, if present, otherwise {#code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}
I understand adding orElse("") as that will assign result to an empty
String.
It doesn't sound like you do understand it to me because that's not a good description of what's happening. Optional.orElse does the following: if the optional contains a value, return that value. If it doesn't contain a value, return whatever argument you've given it.
It's semantically equivalent to the following:
if (optional.ifPresent())
{
return optional.get();
}
else
{
return theArgument;
}
Calling toString, while it will satisfy the compiler, is not what you want to do. You are converting the Optional object itself to a String, not getting the String from inside! While your string will be included, this is only because of how the JDK developers have decided to implement toString. They could equally have not provided an implementation, leaving you with just the default behaviour.
Calling toString on an Optional should basically never be relied upon outside of logging. It's essentially just debugging information. If you do this, then information about the Optional wrapper will be printed as well, which is almost certainly not what you want.
System.out.println(Optional.empty()); // Optional.empty
System.out.println(Optional.of("foo")); // Optional[foo]
If you want result to be null if something along the way returns null then do orElse(null)
String result = Optional.ofNullable(class1)
.map(Class1::getClass2)
.map(Class2::getResult).orElse(null);
Converting the value to String in java; There are multiple ways of doing it.
Just wanted to know what's the difference between each other in the following ways.
strValue.toString()
strValue+""
""+strValue
It depends on java version. Java 7 would act a bit smarter using StringBuilder + append().
Generally, you do not want unnecessary allocations. Use first one.
strValue.toString()
will return itself, because the toString() implementation of String (I'm guessing strValue is indeed of type String) returns this.
strValue+""
""+strValue
Will result in the same value (strValue) but won't invoke the toString() method
All Strings contain the same value, try it out:
String strValue = "Hello world"; // not null
String a = strValue.toString();
String b = strValue+"";
String c = ""+strValue;
Measuring its length give all the result 11, because adding an empty String to another one equals the original String itself:
System.out.println(a.length());
...
Try the equality between these Strings:
System.out.println(a.equals(b));
System.out.println(b.equals(c));
System.out.println(c.equals(a));
They are all true, because these Strings have the same value to be compared. All it in the case the strValue is not null.
One major difference is how null is handled.
If strValue is null, strValue.toString() will throw a NullPointerException, while the other two options will return the String "null".
Other differences may be observed if strValue is of a boxed numeric type, and you try to concatenate other numeric variables to it.
For example :
If
Integer a = 5;
Integer strValue = 6;
Then
a+strValue+""
would return
"11"
while
a+""+strValue
or
""+a+strValue
would return
"56"
This is a follow-up question to some previous questions about String initialization in Java.
After some small tests in Java, I'm facing the following question:
Why can I execute this statement
String concatenated = str2 + " a_literal_string";
when str2 a String object initialized to null (String str2 = null;) but I cannot call the method toString() on str2? Then how does Java do the concatenation of a null String object and a string literal?
By the way, I tried also to concatenate an Integer initialized to null and the string literal "a_literal_string" and I've got the same thing that is "null a_literal_string" in the console. So whichever kind of null gives the same thing?
PS : System.out.println(concatenated); gives null a_literal_string as output in the console.
This line:
String concatenated = str2 + " a_literal_string";
is compiled into something like
String concatenated = new StringBuilder().append(str2)
.append(" a_literal_string")
.toString();
This gives "null a_literal_string" (and not NullPointerException) because StringBuilder.append is implemented using String.valueOf, and String.valueOf(null) returns the string "null".
I tried also to concatenate an Integer initialized to null and the string literal "a_literal_string" and I've got the same thing
This is for the same reason as above. String.valueOf(anyObject) where anyObject is null will give back "null".
I have a json in which userId property is coming as string "null" -
"userId":"null"
I have a method which checks whether my string is null or not -
public static boolean isEmpty(String value) {
return value == null || value.isEmpty();
}
But every time my above method returns back me as false for above userId? It should true since userId is null. Is there any other api in Guava or Apache Commons which can do this?
The value null is not equal to the String "null". null means that a given object has not been assigned a value, where the String "null" is a valid object. It contains the characters n u l l, which is a valid value for a String. You need to also check if the value is the literal string "null" in order to do what you want.
Correct Check
return value == null || value.isEmpty() || value.equals("null") ;
If you want to still maintain "null" as a valid username, then change whatever is sending the json to the following format, which should be interpreted as a literal null rather than a String with content "null"
"userId":null
"null" is not the same as null.
"null" is a string 4 characters in length of the word "null".
null (no quotes) is just that--nothing.
{"userId":"null"} equals String userId = "null" in java.
{} would equal String userId = null when unmarshalled.