amountStr is a value that occasionally contains a double value represented as a string.
I want to use Double.parseDouble to read it into a double variable: amountDbl.
this.amountDbl = Double.parseDouble(amountStr);
It seems to throw a NullPointerException if amountStr doesn't have a value.
Does this mean I have to write a check like this every time?
if(amountStr!=null)
this.amountDbl = Double.parseDouble(amountStr);
Because I have so many statements like this in my code, I'm hoping for a more concise way of doing this check (or avoiding it).
You get a conciser expression if you use the ternary operator:
this.amountDbl = amountStr != null ? Double.parseDouble(amountStr) : 0;
or write your own utility function
public static double parseDoubleOrNull(String str) {
return str != null ? Double.parseDouble(str) : 0;
}
and do
this.ammountDbl = parseDoubleOrNull(ammountStr);
Note however that this doesn't protect you against malformed doubles. If this is a concern I suggest you go with the utility function and do something like this:
public static double parseDoubleSafely(String str) {
double result = 0;
try {
result = Double.parseDouble(str);
} catch (NullPointerException npe) {
} catch (NumberFormatException nfe) {
}
return result;
}
If you're after concise code you could even do
import static pkg.UtilClass.parseDoubleSafely;
Create a wrapper class for the amount that handles this test in the constructor/factory or handles a null amount as a special case, eg the Null option pattern
Use a Java utility library like guava that implements a Optional (expected to come in Guava r10)
Google Guava has a T firstNonNull(T first,T second) that can be used as Double.parseDouble( Objects.firstNonNull(amountStr,"0") )
(Switch to Scala and use the Option Pattern)
Why not initialize it beforehand to a "default" value?
String amountStr = /* some default value */
Then, when you use the variable, check for that special case.
if (amountDbl != /* some default value */)
//parse it
You could always surround it with try/catch or use a ternary operator (as aioobe did)
try{
this.amountDbl = Double.parseDouble(amountStr);
} catch (Exception ex){
ex.printStackTrace();
}
It's not much better but you could do:
this.amountDbl = Double.parseDouble(amountStr==null ? "" : amountString);
Might be a couple of years late to answer this question. The NumberUtils Class in org.apache.commons.lang3.math package has a method createDouble that does what you are asking for(https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/math/NumberUtils.html#createDouble-java.lang.String-)
I was initializing an object and needed to convert from String to Double and ran in to null values from String.
A a = new A(value1, value2 == null ? null : Double.parseDouble(value2), value3....);
I use this:
Double.parseDouble(str.isEmpty()?"0":str);
or
Double.parseDouble((str==null||str.isEmpty())?"0":str);
Related
I'm trying to find an easy way to perform multiple null checks/ replacements in multiple variables in Java.
I have an object with about 20 String variables. In the constructor I want to check if any of the variable values are null. If they are null I want to replace them with an empty String. I could perform a series of if statements but I feel like there must be a cleaner way to do this.
Unless you want to resort to reflection (which I strongly discourage) your best bet is probably to create a helper method (return s == null ? "" : s) and do
field1 = nullToEmpty(field1);
field2 = nullToEmpty(field2);
...
If you already depend on Apache Commons or Guava you can use StringUtils.defaultString or Strings.nullToEmpty.
I agree with aioobe, using reflection is something you should avoid like the plague. But if you are blessed with a project where for example you have to mock a REST interface manually and the objects that come via this interface have tons of Integer, String, Double etc. inside I think you have no other choice.
Here is a generic method that replaces all null pointers it can find in an object with its scalar default values, fills String fields with an empty string and does so recursively if the objects it finds have a parameterless default constructor. Hope this helps other people in the same situation as well.
static void fillNullObjects(Object object) {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
if (field.get(object) != null) {
continue;
}
else if (field.getType().equals(Integer.class)) {
field.set(object, 0);
}
else if (field.getType().equals(String.class)) {
field.set(object, "");
}
else if (field.getType().equals(Boolean.class)){
field.set(object, false);
}
else if (field.getType().equals(Character.class)) {
field.set(object, '\u0000');
}
else if (field.getType().equals(Byte.class)) {
field.set(object, (byte) 0);
}
else if (field.getType().equals(Float.class)) {
field.set(object, 0.0f);
}
else if (field.getType().equals(Double.class)) {
field.set(object, 0.0d);
}
else if (field.getType().equals(Short.class)) {
field.set(object, (short) 0);
}
else if (field.getType().equals(Long.class)) {
field.set(object, 0L);
}
else if (field.getType().getDeclaredFields().length > 0){
for (Constructor<?> constructor : field.getClass().getConstructors()) {
if (constructor.getParameterTypes().length == 0) {
field.set(object, constructor.newInstance());
fillNullObjects(field.get(object));
}
}
}
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
Check out Apache Commons' StringUtils
StringUtils.defaultString(yourString)
This replaces nulls with an empty String. Or you can define your own replacement:
StringUtils.defaultString(null, "foo") // returns "foo"
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html#defaultString(java.lang.String)
Store your variables in an array (or list, if you don't know exacty the number of variables but I don't think so) and loop over it
String[] variables;
//...
for(int i = 0; i < variables.length; i++)
if(variables[i] == null) variables[i] = "";
20 field variables sounds like an egregious case. You should try to avoid explicitly handling that many variables in any situation, or at least factor the code so they are only ever explicitly listed in one place.
A common pattern is to associate each variable with an enumeration, and use the enumeration as a key in a Map with type Enum -> String, or use the enumeration's ordinal as an index into a String array that is sized to the Enumeration value.
Like so:
public enum StringProperties {
TTL, RECVBUF, SENDBUF, RETRIES, ... ;
}
If you wanted explicit default values, you can couple an enumeration with a number of parameters:
public enum StringProperties {
TTL ("100"),
RECVBUF ("1024"),
SENDBUF ("1500"),
RETRIES ("10"),
...
;
public String getDefaultValue() { ... }
}
This strategy means that your code needs minimal modification if you need to add/remove a property, or change a default value.
In your (copy constructor?) case, you can loop over the enumeration values with something like:
for (StringProperties property : StringProperties.values()) {
if (obj.getProperty(property) != null) {
// handle present case
...
} else {
// handle default storage case
...
}
}
Or, like thomas said, you can use a String array on its own, but this assumes that you don't need a way to address each String.
public static String checkNull (String inputString){
if(inputString == null){
inputString = "";
}
return inputString;
}
And just call that whenever you want to check a string.
For each field use the standard Java method:
Objects.toString(field, "");
Avoid constructor with a large number of fields if possible. Use Builder instead (as suggested in Effective Java, Item 2: Consider a builder when faced with many constructor parameters).
I have an array of varying length, and I'd like to read from a fixed position. If the position is out of bounds, I'd like to read a null, instead of throwing. I can of course do something like
if(theArray.length <= colNum){ result = null; }
else{ result = theArray[colNum]; }
but that seems kind of inelegant. I'd like to be able to make a one-liner or simple function call that acts like theArray[colNum] except returns null instead of throwing an out-of-bounds exception. Is there something like that I'm overlooking? Am I overthinking this?
You can use the ternary operator.
Here is a one-liner:
result = ((colNum > theArray.length - 1) || (colNum < 0)) ? null : theArray[colNum];
Depends on what you think is more readable, but you can always use the raised exception:
public String read(String[] array, int index)
{
try
{
return array[index];
}
catch(IndexOutOfBoundsException e)
{
return null;
}
}
It depends, what "elegant" means to you?, There are several of ways for doing it, if you want short code, use the ternary operator:
result = theArray.length <= colNum ? null : theArray[colNum];
Also, you can do the read, and try/catch an ArrayIndexOutOfBoundsException:
try {
result = theArray[colNum];
} catch(ArrayIndexOutOfBoundsException e) {
result = null;
}
And you can encapsulate any of the both in a method, so your invoking code will look like:
result = readFromArray(theArray);
this is my first so I'll try to add as much info as possible so I don't get yelled at. :-)
What I am trying to do is I have 2 variables that grab text from 2 fields and take only the first character from each and assign it to those values.
This is the code that I use to get the strings. They are 2 separate calls as you would.
try { var_ContactSurname = var_ContactSurname.substring(0,1);
}
catch (Exception e){
}
I have the above again with a different variable. Now to this point it does what I want. It grabs the first letter from the fields and assigns it to the variables.
So at this point I have two variables (say with an example charater of D and R).
var_ContactSurname = R
var_ContactLicenceNumber = D
What I want to do is compare those two variables and if they match I want to return a value of TRUE, else FALSE if they don't match.
That value has to be a string as well and be assigned to a new variable called var_ContactValidate.
if (var_ContactLicenceNumber.toLowerCase().equals()var_ContactSurname.toLowerCase()){
var_ContactValidate == "TRUE";
}
else {
var_ContactValidate == "FALSE";
}
No you may notice that there might be some code missing. I am using a rules engine that does a lot of the functions for me. I can use raw Java code to do other things (like this compare)...but that's the compare that I am having a problem with.
Any ideas for that compare would be greatly appreciated.
Thanks.
i would use the String method equalsIgnoreCase()
to assign a value to a field, use a single =, not double (==).
if (var_ContactLicenceNumber.equalsIgnoreCase(var_ContactSurname){
var_ContactValidate = "TRUE";
}
else {
var_ContactValidate = "FALSE";
}
check it
In addition to what already said - a simpler & more elegant version (without the if condition) could be:
var_ContactValidate = Boolean.toString(
var_ContactLicenceNumber.equalsIgnoreCase(var_ContactSurname))
.toUpperCase();
Change your whole piece of code to:
if (var_ContactLicenceNumber.equalsIgnoreCase(var_ContactSurname)){
var_ContactValidate == "TRUE";
}
else {
var_ContactValidate == "FALSE";
}
This combines the case insensitivity that you want, and passes through the second string as an argument of the .equalsIgnoreCase function.
Also, I am not sure what you are trying to do with the line:
var_ContactValidate == "TRUE";
If you want to assign var_ContactValidate to "TRUE" then use a single equals sign '=' as a double equals '==' compares the values instead. You may also considering using a boolean rather than a string in this case.
Here is an implementation that also checks for null values and empty Strings:
public class SurnameAndLicenseValidator {
public static void main(String[] args) {
// FALSE
validateSurnameAndLicense(null, "jb78hq");
validateSurnameAndLicense("Johnson", null);
validateSurnameAndLicense(null, null);
validateSurnameAndLicense("", "jb78hq");
validateSurnameAndLicense("Johnson", "");
validateSurnameAndLicense("", "");
validateSurnameAndLicense("johnson", "xb78hq");
// TRUE
validateSurnameAndLicense("Johnson", "jb78hq");
validateSurnameAndLicense("johnson", "jb78hq");
}
private static String validateSurnameAndLicense(String surname,
String license) {
String result;
if (surname != null
&& surname.length() > 0
&& license != null
&& license.length() > 0
&& Character.toUpperCase(surname.charAt(0)) == Character
.toUpperCase(license.charAt(0))) {
result = "TRUE";
} else {
result = "FALSE";
}
System.out.println(surname + " " + license + " " + result);
return result;
}
}
The main method is used as a unit test here. You might want to extract a real JUnit test from it, if you are into that kind of thing.
I have a function that concatenate a set of strings like this:
StringBuffer sb = new StringBuffer();
sb.append(fct1());
sb.append(fct2());
sb.append(fct3());
Where fct1(), fct2() and fct3() should return a String.
The problem is that I must test the returned values like this :
sb.append(fct1() == null ? "" : fct1());
because I get an exception if the value is null.
The problem is that I have many instructions like this and, above all, I can't modify these functions that return the strings(fct1, fct2 and fct3).
Is there a solution that will "sanitize" automatically my strings?
Thank you.
PS: I created a function that can do it:
public String testNullity(String aString){
aString == null ? "" : aString;
}
so that I can call it like this:
sb.append(testNullity(fct1));
sb.append(testNullity(fct2));
...
Another alternative might be
public class SafeStringBuilder {
private StringBuilder builder = new StringBuilder();
public SafeStringBuilder append(String s) {
if (s != null)
builder.append(s);
return this;
}
}
If you don't mind introducing a dependency, use Guava's Joiner instead of StringBuffer:
Joiner j = Joiner.on("").skipNulls();
StringBuilder sb = new StringBuilder();
j.appendTo(sb, fct1());
j.appendTo(sb, fct2());
j.appendTo(sb, fct3());
String result = sb.toString();
// or even just
Joiner j = Joiner.on("").skipNulls();
String result = j.join(fct1(), fct2(), fct3());
N.B. In general, unless you need StringBuffer's thread safety, you should use StringBuilder instead. Same API, better performance.
There is nothing whatsoever you can do to make this solution simpler except shortening the method name. (There might be a solution using aspect-oriented programming, but on the whole I don't really consider that simpler.)
Unfortunately your solution with testNullity() is the best you can get with Java (consider better naming though). In fact, there is already a method that does that: StringUtils.html#defaultString.
You can create your own wrapper around StringBuffer:
class MyStringBuffer {
StringBuffer _sb = new StringBuffer();
public boolean append(String s) {
_sb.append(s==null ? "" : s);
return s == null;
}
public String toString() { return _sb.toString(); }
}
There is no such function in the standard API, though some methods (which do other things) have it built in.
For example, System.getProperty() has a variant which takes a default value, and if it can't find the given property, it will not return null, but the given default value. You might think of providing your fct* methods with such a "default" argument, if it makes sence.
I think C# has a ?? operator which does about what you want (you would call sb.append(fct2() ?? "")), but I suppose Java will not add any new operators soon.
A better variant of your checking function would be this:
public void appendIfNotNull(StringBuffer sb, String s) {
if(s != null) {
sb.append(s);
}
}
This avoids the superfluous append call with an empty string if there is nothing to append.
Greetings,
I'm trying to validate whether my integer is null. If it is, I need to prompt the user to enter a value. My background is Perl, so my first attempt looks like this:
int startIn = Integer.parseInt (startField.getText());
if (startIn) {
JOptionPane.showMessageDialog(null,
"You must enter a number between 0-16.","Input Error",
JOptionPane.ERROR_MESSAGE);
}
This does not work, since Java is expecting boolean logic.
In Perl, I can use "exists" to check whether hash/array elements contain data with:
#items = ("one", "two", "three");
##items = ();
if (exists($items[0])) {
print "Something in \#items.\n";
}
else {
print "Nothing in \#items!\n";
}
Is there a way to this in Java? Thank you for your help!
Jeremiah
P.S. Perl exists info.
parseInt() is just going to throw an exception if the parsing can't complete successfully. You can instead use Integers, the corresponding object type, which makes things a little bit cleaner. So you probably want something closer to:
Integer s = null;
try {
s = Integer.valueOf(startField.getText());
}
catch (NumberFormatException e) {
// ...
}
if (s != null) { ... }
Beware if you do decide to use parseInt()! parseInt() doesn't support good internationalization, so you have to jump through even more hoops:
try {
NumberFormat nf = NumberFormat.getIntegerInstance(locale);
nf.setParseIntegerOnly(true);
nf.setMaximumIntegerDigits(9); // Or whatever you'd like to max out at.
// Start parsing from the beginning.
ParsePosition p = new ParsePosition(0);
int val = format.parse(str, p).intValue();
if (p.getIndex() != str.length()) {
// There's some stuff after all the digits are done being processed.
}
// Work with the processed value here.
} catch (java.text.ParseFormatException exc) {
// Something blew up in the parsing.
}
Try this:
Integer startIn = null;
try {
startIn = Integer.valueOf(startField.getText());
} catch (NumberFormatException e) {
.
.
.
}
if (startIn == null) {
// Prompt for value...
}
ints are value types; they can never be null. Instead, if the parsing failed, parseInt will throw a NumberFormatException that you need to catch.
There is no exists for a SCALAR in Perl, anyway. The Perl way is
defined( $x )
and the equivalent Java is
anInteger != null
Those are the equivalents.
exists $hash{key}
Is like the Java
map.containsKey( "key" )
From your example, I think you're looking for
if ( startIn != null ) { ...
For me just using the Integer.toString() method works for me just fine. You can convert it over if you just want to very if it is null. Example below:
private void setCarColor(int redIn, int blueIn, int greenIn)
{
//Integer s = null;
if (Integer.toString(redIn) == null || Integer.toString(blueIn) == null || Integer.toString(greenIn) == null )
I don't think you can use "exists" on an integer in Perl, only on collections. Can you give an example of what you mean in Perl which matches your example in Java.
Given an expression that specifies a hash element or array element, returns true if the specified element in the hash or array has ever been initialized, even if the corresponding value is undefined.
This indicates it only applies to hash or array elements!
This should help.
Integer startIn = null;
// (optional below but a good practice, to prevent errors.)
boolean dontContinue = false;
try {
Integer.parseInt (startField.getText());
} catch (NumberFormatException e){
e.printStackTrace();
}
// in java = assigns a boolean in if statements oddly.
// Thus double equal must be used. So if startIn is null, display the message
if (startIn == null) {
JOptionPane.showMessageDialog(null,
"You must enter a number between 0-16.","Input Error",
JOptionPane.ERROR_MESSAGE);
}
// (again optional)
if (dontContinue == true) {
//Do-some-error-fix
}