There's a key difference between a null array and an empty array. This is a test for null.

int arr[] = null;
if (arr == null) {
  System.out.println("array is null");
}

"Empty" here has no official meaning. I'm choosing to define empty as having 0 elements:

arr = new int[0];
if (arr.length == 0) {
  System.out.println("array is empty");
}

An alternative definition of "empty" is if all the elements are null:

Object arr[] = new Object[10];
boolean empty = true;
for (int i=0; i<arr.length; i++) {
  if (arr[i] != null) {
    empty = false;
    break;
  }
}

or

Object arr[] = new Object[10];
boolean empty = true;
for (Object ob : arr) {
  if (ob != null) {
    empty = false;
    break;
  }
}
Answer from cletus on Stack Overflow
🌐
Overclock.net
overclock.net › home › forums › software, programming and coding › coding and programming
How can I set an element in an array to null? (java) | Overclock.net
This is what I did: for(j = 0; j < 10; j++) // j is which element in list { compare = delpass.compareTo(pw[j]); if(compare == 0) pw[j].equals(null); //pw and nm are arrays nm[j].equals(null); } delpass is the password the user wants to delete, so basically I am finding the element that matches this password and trying to set it equal to null again but I cant because null is a java key term.
Top answer
1 of 16
213

They're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.

For instance:

class Foo {
    private int data;

    Foo(int d) {
        this.data = d;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != this.getClass()) {
           return false;
        }
        return ((Foo)other).data == this.data;
    }

    /* In a real class, you'd override `hashCode` here as well */
}

Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances

System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition

Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it

System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything

System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
2 of 16
52

In addition to the accepted answer (https://stackoverflow.com/a/4501084/6276704):

Since Java 1.7, if you want to compare two Objects which might be null, I recommend this function:

Objects.equals(onePossibleNull, twoPossibleNull)

java.util.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.

Since: 1.7

🌐
Medium
medium.com › @AlexanderObregon › javas-arrays-equals-method-explained-271f9420177d
Java’s Arrays.equals() Method Explained | Medium
September 11, 2024 - If one array is null and the other is not, the method returns false. This reflects that a null array and a non-null array are not equal.
🌐
Stack Overflow
stackoverflow.com › questions › 31495855 › java-equals-method-regarding-null-in-array
Java equals method regarding null in array - Stack Overflow
In the code fragment below I was told that in the if statement, the position of this.item[i] and item cannot be swapped, because there might be a null in the item[i] array. I don't understand why... what I was told works: if(this.item[i].equals(item)) what I was told doesn't work: if(item.equals(this.item[i]))
Top answer
1 of 9
352

array1.equals(array2) is the same as array1 == array2, i.e. is it the same array. As @alf points out it's not what most people expect.

Arrays.equals(array1, array2) compares the contents of the arrays.


Similarly array.toString() may not be very useful and you need to use Arrays.toString(array).

2 of 9
101

It's an infamous problem: .equals() for arrays is badly broken, just don't use it, ever.

That said, it's not "broken" as in "someone has done it in a really wrong way" — it's just doing what's defined and not what's usually expected. So for purists: it's perfectly fine, and that also means, don't use it, ever.

Now the expected behaviour for equals is to compare data. The default behaviour is to compare the identity, as Object does not have any data (for purists: yes it has, but it's not the point); assumption is, if you need equals in subclasses, you'll implement it. In arrays, there's no implementation for you, so you're not supposed to use it.

So the difference is, Arrays.equals(array1, array2) works as you would expect (i.e. compares content), array1.equals(array2) falls back to Object.equals implementation, which in turn compares identity, and thus better replaced by == (for purists: yes I know about null).

Problem is, even Arrays.equals(array1, array2) will bite you hard if elements of array do not implement equals properly. It's a very naive statement, I know, but there's a very important less-than-obvious case: consider a 2D array.

2D array in Java is an array of arrays, and arrays' equals is broken (or useless if you prefer), so Arrays.equals(array1, array2) will not work as you expect on 2D arrays.

🌐
Coderanch
coderanch.com › t › 399694 › java › null-equals-null
null equals null? (Beginning Java forum at Coderanch)
So even though the arrays have the same content, the .contains() fails because the arrays are not ==. What you would need to do is write a class that wraps around an array and override .equals() on that class to interate through the array and see if the elements of the array are equal.
🌐
Reddit
reddit.com › r/javahelp › need some help debugging. exception in thread "main" java.lang.nullpointerexception: cannot invoke "object.equals(object)" because "this.items[i]" is null
r/javahelp on Reddit: Need some help debugging. Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Object.equals(Object)" because "this.items[i]" is null
July 23, 2023 -
public class ArraySet<T> {
    private T[] items;
    private int size;

    public ArraySet() {
        items = (T[]) new Object[100];
        size = 0;
    }

    public void add(T value) {
        for (int i = 0; i < size; i++) {
            if (items[i] == value) {
                return;
            }
        }
        items[size + 1] = value;
        size ++;
    }

    public boolean contains(T x) {
        for (int i = 0; i < size; i++) {
            if (items[i].equals(x)) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        ArraySet<String> s = new ArraySet<>();
        // test add function
        s.add("horse");
        System.out.println(s.size);
        s.add("fish");
        System.out.println(s.size);
        // test contains function
        System.out.println(s.contains("horse"));
    }
}

I self create an Arrayset class to store strings with add function and contains function, but the contains function goes wrong. I try to modify my add function but it doesn't works.

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Object.equals(Object)" because "this.items[i]" is null

Find elsewhere
Top answer
1 of 1
14

First up, yes, you're right that the second null check is redundant. If obj is null then the method will return false on the first check:

    if (!(obj instanceof ArrayOfColumn)) return false;

Of course, that would better be written:

    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }

But, that's the least of my concerns. The synchronized equals is probably there because other methods are synchronized, but synchronization comes at a cost. Unless you are sure you need it, remove it.

Additionally, synchronized methods are seldom the best solution. It is normally better to have tighter control of your locks so that nobody but you can hold them. That normally means using a private, internal "monitor" for synchronization:

private final Objct lock = new Object();

private boolean equals(Object obj) {
    synchronized(lock) {
        .....
    }
}

Using the private lock prevents other people from hanging your application by using your class as their own monitor. Imagine if your class is called MyClass, and someone does:

 private MyClass instance = new MyClass();

 synchronized(instance) {
     Thread.sleep(10000);
 }

If they did the above, your methods in other threads would never run, and your application would "hang".

Now, abut the __equalsCalc variable. It does nothing useful. It is set, and then cleared, inside the synchronized method, and, as a result, it will never, ever have any value in it that is useful. It is completely redundant and a waste of time.

Oh, and what's with the fully qualified java.lang.Object? Just use Object.

I would rewrite the method as (using the same synchronized method to be compatible with other methods in your class):

public synchronized boolean equals(Object obj) {
    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    ArrayOfColumn other = (ArrayOfColumn) obj;
    if (getColumn() == null) {
        return other.getColumn() == null;
    }
    return other.getColumn() != null && Arrays.equals(column, other.getColumn());
}

Note that you still have a synchronization vulnerability - the other column's column could be changed between checking for whether it's column is null, and using the column in the equals. You could still get null pointer exceptions if someone changes the other column in the middle of your equals. You should consider synchronizing on that other column too:

public synchronized boolean equals(Object obj) {
    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    ArrayOfColumn other = (ArrayOfColumn) obj;
    synchronized(other) {
        if (getColumn() == null) {
            return other.getColumn() == null;
        }
        return other.getColumn() != null && Arrays.equals(column, other.getColumn());
    }
}

Unfortunately, cross-synchronizing like that can lead to deadlocks if you are not careful.

🌐
DataCamp
datacamp.com › doc › java › equals
Java Array equals()
Null Handling: If either of the arrays being compared is null, Arrays.equals() returns false unless both are null, in which case it returns true. Avoid Manual Loops: Instead of writing manual loops to compare arrays, use Arrays.equals() for cleaner and more readable code.
🌐
Coderanch
coderanch.com › t › 545457 › java › comparing-values-equalsIgnoreCase-equals-NULL
comparing two values with equalsIgnoreCase and equals with NULL as first value. (Java in General forum at Coderanch)
If one is null and other has values,if these are assigned at run time ; how do I compare with equalsIgnoreCase and equals() ? Apparently null is different from any other value,so I HAVE TO EXPECT null and other values in both elements. This happends for only first element. How do I write a refined code for comparing two values considering or expecting null ? if I use the following way,its not correct ... Find the java.util.Objects class, which has equals() methods overloaded to take two parameters, and can cope with null values.
🌐
TutorialsPoint
tutorialspoint.com › home › java/util › java arrays equals method
Java Arrays Equals Method
September 1, 2008 - The Java Arrays equals(Object[] ... e1 and e2 are considered equal if Objects.equals(e1, e2). In case of any array null, a NullPointerException is thrown....
🌐
Blogger
javarevisited.blogspot.com › 2012 › 12 › how-to-compare-arrays-in-java-equals-deepequals-primitive-object.html
How to Compare Arrays in Java – Equals vs deepEquals Example
On the other hand Arrays.deepEquals() method compares recursively if an array contains another array. Arrays.equals() check is if the element is null or not and then calls equals() method, it does not check for Array type.
🌐
TutorialsPoint
tutorialspoint.com › comparing-strings-with-possible-null-values-in-java
Comparing Strings with (possible) null values in java?
In the same way the equals() method of the object class accepts two String values and returns a boolean value, which is true if both are equal (or, null) and false if not. import java.util.Scanner; public class CompringStrings { public static void main(String args[]) { Scanner sc = new ...
Top answer
1 of 7
73

No.

An ArrayList can be empty (or with nulls as items) an not be null. It would be considered empty. You can check for am empty ArrayList with:

ArrayList arrList = new ArrayList();
if(arrList.isEmpty())
{
    // Do something with the empty list here.
}

Or if you want to create a method that checks for an ArrayList with only nulls:

public static Boolean ContainsAllNulls(ArrayList arrList)
{
    if(arrList != null)
    {
        for(object a : arrList)
            if(a != null) return false;
    }

    return true;
}
2 of 7
23

arrayList == null if there are no instance of the class ArrayList assigned to the variable arrayList (note the upercase for classes and the lowercase for variables).

If, at anytime, you do arrayList = new ArrayList() then arrayList != null because is pointing to an instance of the class ArrayList

If you want to know if the list is empty, do

if(arrayList != null && !arrayList.isEmpty()) {
 //has items here. The fact that has items does not mean that the items are != null. 
 //You have to check the nullity for every item

}
else {
// either there is no instance of ArrayList in arrayList or the list is empty.
}

If you don't want null items in your list, I'd suggest you to extend the ArrayList class with your own, for example:

public class NotNullArrayList extends ArrayList{

@Override
public boolean add(Object o) 
   { if(o==null) throw new IllegalArgumentException("Cannot add null items to the list");
      else return super.add(o);
    }
}

Or maybe you can extend it to have a method inside your own class that re-defines the concept of "empty List".

public class NullIsEmptyArrayList extends ArrayList{

@Override
public boolean isEmpty() 
   if(super.isEmpty()) return true;
   else{
   //Iterate through the items to see if all of them are null. 
   //You can use any of the algorithms in the other responses. Return true if all are null, false otherwise. 
   //You can short-circuit to return false when you find the first item not null, so it will improve performance.
  }
}

The last two approaches are more Object-Oriented, more elegant and reusable solutions.

Updated with Jeff suggestion IAE instead of NPE.

🌐
DeepSource
deepsource.com › directory › java › issues › JAVA-E0110
`equals` method does not handle null valued operands (JAVA-E0110) ・ Java
Python JavaScript Java Go C# Ansible AWS CloudFormation Linter C & C++ Dart Analyze Docker Kotlin KubeLinter PHP Ruby Rust Scala Secrets Shell Slither Solhint SQL Swift Terraform Test coverage · Audit: Biometric authentication should always be used with a cryptographic objectJAVA-A1030Non-constant string passed to `execute` or `addBatch` method on an SQL statementJAVA-S0082`equals` method does not handle null valued operandsJAVA-S0110Reference to mutable object which is returned may expose internal representation of dataJAVA-S0132Reference to externally mutable object stored as internal state
🌐
Java Tutorial HQ
javatutorialhq.com › java tutorial › java.util › arrays › equals() method example
Java Arrays equals() method example
October 2, 2019 - Also, two array references are considered equal if both are null. Notes: The equals() had one deficiency, it will not be able to test properly the equality of multi dimensional array.