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.
🌐
Medium
medium.com › @AlexanderObregon › javas-arrays-equals-method-explained-271f9420177d
Java’s Arrays.equals() Method Explained | Medium
September 11, 2024 - If both arrays are null, the method returns true. This is based on the idea that two null arrays can be considered equal because they both represent the absence of data.
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

🌐
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.
Find elsewhere
🌐
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

🌐
TutorialsPoint
tutorialspoint.com › when-does-a-java-array-throws-a-nullpointerexception
When does a Java Array Throws a NullPointerException?
If you try to access the elements of an array which is not initialized yet (which is null). public class Demo { public static void main(String args[]) { int myArray[] = null; System.out.println(myArray[5]); } } Exception in thread "main" java.lang.NullPointerException at july_set3.Demo.main(Demo.java:6)
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.

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.

🌐
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.
🌐
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.
🌐
TutorialsPoint
tutorialspoint.com › comparing-strings-with-possible-null-values-in-java
Comparing Strings with (possible) null values in java?
import java.util.Scanner; public class CompringStrings { public static void main(String args[]) { Scanner sc = new Scanner(System.in); System.out.println("Enter your first string value: "); String str1 = sc.next(); System.out.println("Enter your second string value: "); String str2 = sc.next(); //Comparing two Strings int res = str1.compareTo(str2); System.out.println(res); if(res==0) { System.out.println("Both Strings are null or equal"); }else if(res<0){ System.out.println(""+str1+" preceeds "+str2+""); }else if(res>0){ System.out.println(""+str2+" preceeds "+str1+""); } } }
🌐
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 › home › java/util › java arrays equals method
Java Arrays Equals Method
September 1, 2008 - The Java Arrays equals(Object[] ... e2 are considered equal if Objects.equals(e1, e2). In case of any array null, a NullPointerException is thrown....