Compare two objects in Java with possible null values
This is what Java internal code uses (on other compare
methods):
public static boolean compare(String str1, String str2) {
return (str1 == null ? str2 == null : str1.equals(str2));
}
Comparing two objects, either of which could be null
There is new utility class available in jdk since 1.7 that is Objects
.
This class consists of static utility methods for operating on
objects. These utilities include null-safe or null-tolerant methods
for computing the hash code of an object, returning a string for an
object, and comparing two objects.
You can use Objects.equals
, it handles null.
Objects.equals(Object a, Object b) Returns true if the arguments are equal to each other and false
otherwise. Consequently, if both arguments are null, true is returned
and if exactly one argument is null, false is returned. Otherwise,
equality is determined by using the equals method of the first
argument.
if(Objects.equals(myString,myString2)){...}
How to compare two Strings when both can be null?
If Java 7+, use Objects.equals()
; its documentation explicitly specifies that:
[...] if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument.
which is what you want.
If you don't, your method can be rewritten to:
return s1 == null ? s2 == null : s1.equals(s2);
This works because the .equals()
contract guarantees that for any object o
, o.equals(null)
is always false.
compare an object to null!
Try c != null in your if statement. You're not comparing the objects themselves, you're comparing their references.
Compare two objects with a check for null
Java 7.0 added a new handy class: Objects
.
It has a method exactly for this: Objects.equals(Object a, Object b)
Compare 2 objects ignoring null values
I finally created my own asserts like this:
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.Assertions;
import java.util.List;
import java.util.stream.Collectors;
public class Object1Assert extends AbstractAssert<Object1Assert, Object1> {
public Object1Assert isEqualTo(Object1 other) {
// specially for null
if(actual == other) {return this;}
if(actual.getObject2() != null) {
Assertions.assertThat(other.getObject2()).isEqualToIgnoringNullFields(actual.getObject2());
}
if(actual.getObject3() != null) {
for(Object3 object3 : actual.getObject3()) {
my.package.Assertions.assertThat(object3).isIn(other.getObject3());
}
}
// return the current assertion for method chaining
return this;
}
public Object1Assert(Object1 actual) {
super(actual, Object1Assert.class);
}
public static Object1Assert assertThat(Object1 actual) {
return new Object1Assert(actual);
}
}
public class Assertions {
public static Object3Assert assertThat(Object3 actual) {
return new Object3Assert(actual);
}
}
public class Object3Assert extends AbstractAssert<Object3Assert, Object3> {
public Object3Assert isIn(List<Object3> others) {
List<String> otherStringIds = others.stream().map(Object3::getStringId).collect(Collectors.toList());
Assertions.assertThat(otherStringIds).isNotEmpty();
Assertions.assertThat(actual.getStringId()).isIn(otherStringIds);
for (Object3 otherObject3 : others) {
if(actual.getStringId().equalsIgnoreCase(otherObject3.getStringId())) {
Assertions.assertThat(otherObject3).usingComparatorForType(Comparators.bigDecimalComparator, BigDecimal.class).isEqualToIgnoringNullFields(actual);
}
}
// return the current assertion for method chaining
return this;
}
public Object3Assert(Object3 actual) {
super(actual, Object3Assert.class);
}
public static Object3Assert assertThat(Object3 actual) {
return new Object3Assert(actual);
}
}
I created this class for each type I needed with this tutorial
https://www.baeldung.com/assertj-custom-assertion
Related Topics
Replacing If Else Statement with Pattern
Injecting Beans into a Class Outside the Spring Managed Context
Which Artifacts Should I Use for Jaxb Ri in My Maven Project
Can't a Swing Component Be Added to Multiple Containers
Is Gnu's Java Compiler (Gcj) Dead
Is There a Good Reason to Use "Printf" Instead of "Print" in Java
Java: Setcellvaluefactory; Lambda VS. Propertyvaluefactory; Advantages/Disadvantages
Calculating the Distance Between Two Points
What Does It Mean When They Say Http Is Stateless
Transform Java Future into a Completablefuture
What Is Inside Com.Sun Package
Throw Checked Exceptions from Mocks with Mockito
What Is the Regex for "Any Positive Integer, Excluding 0"
Keylistener, Keypressed Versus Keytyped
How to Enable Commit on Focuslost for Tableview/Treetableview
How to Improve Performance of This Regular Expression Further