This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 7 years ago.
Can any Java proficient / expert suggest me what is the optimistic way of checking null reference or objects before using it to avoids NullPointerException?
In my code I've more than 100 fields and most of them are required in order to pass value in request, but I need to perform null checks every time before passing it in request to avoid NullPointerException
I have shown below a little piece of code where I'm checking for null values every time for each field (lets say of more 70 times in my one file) which looks not good, code become very ugly and unreadable. Is there any way by which we can write method and perform null object checks through it?
Basically I'm looking better, Optimistic and faster way for doing this, Any quick help is much needed.
if(amount != null && amount != "" && !amount.isEmpty())
AIMRequest.put("x_Amount", amount);
if(currency != null && currency != "" && !currency.isEmpty())
AIMRequest.put("x_Currency_Code", currency);
if(expDate != null && expDate != "" && !expDate.isEmpty())
AIMRequest.put("x_Exp_Date", expDate);
...........so on
add("x_Amount", amount);
add("x_Currency_Code", currency);
add("x_Exp_Date", expDate);
void add(String name, String value)
{
if(value!=null && !value.isEmpty())
AIMRequest.put(name, value);
}
According your if's, conditions you are comparing Strings, so make a method:
public boolean isValid(String s) {
return s != null && s != "" && !s.isEmpty();
}
If you want to compare objects with this methods change the signature public boolean isValid(Object o),
and your code will be clean as this:
if(isValid(amount))
AIMRequest.put("x_Amount", amount);
if(isValid(currency)
AIMRequest.put("x_Currency_Code", currency);
if(isValid(expDate)
AIMRequest.put("x_Exp_Date", expDate);
But if you can collect all objects in an array:
public boolean isValid(Object[] os) {
for (String s : os) {
boolean isValid = s != null && s != "" && !s.isEmpty();
if (!isValid) return false;
}
return true;
}
Related
This question already has answers here:
how to check multiple string value are empty or blank at one shot using java
(2 answers)
Closed 1 year ago.
I'm validating given string is null, isEmpty or isBlank and I've use case where I've to check either productId or productItem should present or productName and productPrice should contains value. For that I've written below if condition but it looks very clumsy and not readable. Can someone please help me how can we simplify this if condition and write in more readable format.
public class validate {
public static void main(String[] args) {
String productId = "";
String productItem = "";
String productName = "Apple";
String productPrice = "1500";
if ((!productId.isEmpty() && !productId.isBlank() && productId != null
|| !productItem.isEmpty() && !productItem.isBlank() && productItem != null)
|| (!productName.isEmpty() && !productName.isBlank() && productName != null
&& !productPrice.isEmpty() && !productPrice.isBlank() && productPrice != null)) {
System.out.println("valid");
} else {
System.out.println("not valid");
}
}
}
In general, you can often simplify code by defining auxiliary methods.
Define this helper:
boolean isNullEmptyOrBlank(String s) {
return s == null || s.isEmpty() || s.isBlank());
}
then
if (isNullEmptyOrBlank(productId) && isNullEmptyOrBlank(productItem) && isNullOrEmptyOrBlank(productName)) {
// invalid - unknown product
}
else if (isNullOrEmptyOrBlank(productValue)) {
// invalid - unknown price
}
else {
// valid
}
I'm not sure if I got your intended logic correct, but you should get the idea.
In practice, I'd probably decide isNullEmptyOrBlank was a clunky name, and call it something like isSet instead.
The following Java snippet of code confuses me a bit. The method is trying to check whether two objects are NOT equal, using the standard .equals() method to denote that they are equal. Additionally, a boolean can determine whether two null's are considered equal or not. I'm wondering if:
The boolean logic in this method is indeed correct?
the return statement in the middle block can be omitted somehow. Could this logic be rewritten in a more concise or other way, maybe dropping the empty return, but keeping a high level of human readability of the code?
Snippet:
public static void verifyVariableIsNotEqualTo(Object variable, Object otherVariable, boolean considerBothNullAsEqual)
{
if(considerBothNullAsEqual && variable == null && otherVariable == null)
{
throw new Exception("not allowed to be equal");
}
if(variable == null || otherVariable == null)
{
return;
}
if(variable.equals(otherVariable))
{
throw new Exception("not allowed to be equal");
}
}
Yes, the logic in the method is correct. It throws the exception if the two objects are equal. You could remove the second condition and combine it with the third one, but I don't see much point. If you did, the method might look like this.
public static void verifyVariableIsNotEqualTo(Object variable, Object otherVariable, boolean considerBothNullAsEqual) throws Exception
{
if(considerBothNullAsEqual && variable == null && otherVariable == null)
{
throw new Exception("not allowed to be equal");
}
if(variable != null && variable.equals(otherVariable))
{
throw new Exception("not allowed to be equal");
}
}
Note that there's no need to check whether otherVariable is null separately, since the equals method on variable should return false if otherVariable is null.
There's an even more concise way to write this, but it's not worth considering, since it sacrifices readability.
I am using Sonar and its giving me the suggestion "Expressions should not be too complex"
How can I make a better representation of below code?
Code
if (eDelivery != null && Boolean.parseBoolean(eDelivery.getReceiveConfirmationElectronically()) &&
!Boolean.parseBoolean(eDelivery.getInvalidEmailAddress()) && !Boolean.parseBoolean(eDelivery.getEmailUndeliverable()) &&
eDelivery.getUserEmailAddress() != null && !eDelivery.getUserEmailAddress().isEmpty()) {
// Implementation code
}
These conditions all relate to the eDelivery object, so deal with this there.
First, there's the question of why you're doing all these parseBoolean calls for properties that look like they should be boolean to start with. But okay, let's assume that you can't change that. Fine, so add 2ndary methods:
public class EDelivery {
public boolean isReceiveConfirmationElectronically() {
return Boolean.parseBoolean(getReceiveConfirmationElectronically())
}
// &etc...
Already that cleans it up considerably:
if (eDelivery != null && eDelivery.isReceiveConfirmationElectronically() &&
!eDelivery.isInvalidEmailAddress() && !eDelivery.isEmailUndeliverable() &&
eDelivery.getUserEmailAddress() != null && !eDelivery.getUserEmailAddress().isEmpty()) {
// Implementation code
But that doesn't address the number of conditions. So now:
// in EDelivery class
public boolean isEmailGood() {
return !isInvalidEmailAddress() && !isEmailUndeliverable() &&
getUserEmailAddress() != null && !getUserEmailAddress().isEmpty())
}
So now we're at:
if (eDelivery != null && eDelivery.isReceiveConfirmationElectronically() &&
eDelivery.isEmailGood()) {
// Implementation code
At this point you've met the requirement, but if you wanted to take it a little further:
// in EDelivery class
public boolean canSendElectronicConfirmation(){
return isEmailGood() && isReceiveConfirmationElectronically();
}
Which reduces your original if statement to
if (eDelivery != null && eDelivery.canSendElectronicConfirmation()) {
// Implementation code
Pardon me if this is a stupid question.. I was wondering if there is any support for following comparison in Java:
(a, b, c .... != null) in place for :
(a != null && b != null && c != null && d ! null and so on ..)
I was trying to make code more readable as my code which is almost unreadable due to multiple condition in single statement.
code :
variable = (rest.host != null && rest.payload != null
&& rest.lockQueue != null && rest.endpoint != null ) || rest.default.setState
|| rest.scheduler.locked && rest.scheduler.queue.isFull()
&& lastPayload.getActivity.status.executing ? onExecute(rest.payload) : wait(TIME);
If your elements are in a collection, use collection.stream().allMatch(x -> x != null). Actually, there's even a predicate for that: collection.stream().allMatch(Objects::nonNull).
If your elements aren't in a collection, you can still use Arrays.asList() to create an ad-hoc list from them. So, in your case:
Arrays.asList(rest.host, rest.payload, rest.lockQueue, rest.endpoint).stream().allMatch(Objects::nonNull)
EDIT: actually, as someone mentioned in another answer, there is a method that creates a stream directly, namely Stream.of(...). So:
Stream.of(rest.host, rest.payload, rest.lockQueue, rest.endpoint).allMatch(Objects::nonNull)
You could do something like this to make sure everything is not null, if using a Java version lower than 8. Otherwise I would go with the other people's answers using streams.
private boolean checkIfNotNull( Object ... objects ) {
for(int i = 0; i < objects.length; i++) {
if(objects[i] == null)
return false;
}
return true;
}
and you could pass in all the objects that you want to check if they are null.
then you can call this in the if statement such as
if( checkIfNotNull( a, b, c, d, e, f, g ) ) {
//do stuff
}
In java 8, it could be done as next Stream.of(a, b, c, d).allMatch(Objects::nonNull), it will return true if they are all non null.
I think if you want your code more readable, you should replace your comparisons with method calls that "says" what each comparison is.
Example:
if (isAllRight(a, b, c)) {
...
}
In other cases you can break them into single comparisons and check one by one:
if (a == NUL) {
return false;
}
if (b == NULL) {
return false;
}
return true;
is it possible to do something like
criteria.add(Expression.eq("product", " * "))
for it to match everything ?
It would be handy in case that you get a variable that can have many values and a special value "all" that matches against everything. So you can call a method like this and if the variable had a value of "all", then the expression would match everything.
public void someFunction(String variable) {
criteria.add(Expression.eq("product", variable))
}
EDITED: If I had 2 select fields with Source Language & Destination Language and a table listing entries based on which language combination it contains, with IF STATEMENTS it would look like this: (DynamicQuery is an abstraction for Criteria)
private DynamicQuery addCriteria(DynamicQuery dq, String languageFrom, String languageTo){
if (null != languageFrom && !languageFrom.isEmpty() && null != languageTo && !languageTo.isEmpty()){
if(languageFrom.equals("All") && languageTo.equals("All")) {
return dq;
} else if (!languageFrom.equals("All") && !languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFrom));
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageTo));
return dq;
} else if (languageFrom.equals("All") && !languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageTo));
return dq;
} else if (!languageFrom.equals("All") && languageTo.equals("All")) {
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFrom));
return dq;
}
}
}
It's disgusting, consider there would be one more field, it would be even more disgusting...One simply must cover all the combinations that might occur ... That's why I would like to have something like REGEX, because I would assign variable the reqex "*" value and I would add two lines like this
dq.add(PropertyFactoryUtil.forName("languageFrom").eq(languageFromVariable));
dq.add(PropertyFactoryUtil.forName("languageTo").eq(languageToVariable));
if (null != variable && !variable.isEmpty()){
criteria.add(Expression.eq("product", variable)) ;
}
If you only need it when it is selected. You may wanna add an if statement so criteria is added only when needed.
Edit 1:
You can define a method if you are gonna use it for more than fields. Even you can define different criterias inside here. Easy maintance (as is used by all and centrilized), code reuse (change at one point at it will be effective to all)
addCriteria(Criteria criteria, String name, String value){
//you wanna handle special cases like null == name as well accordingly
if (null != value && !value.isEmpty() && null != name && !name.isEmpty()){
criteria.add(Expression.eq(name, value)) ;
}
}