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 OverflowThere'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;
}
}
ArrayUtils.isNotEmpty(testArrayName) from the package org.apache.commons.lang3 ensures Array is not null or empty
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
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
When I type
string1 == string2
IntelliJ tells me to switch to equals(), which it says is null-safe.
But is == operator not null-safe?
I tried null == "abc", "abc" == null, null == null, but they consistently gave me right false false true.
What am I missing here?
Technically speaking, there's no such thing as a null array; but since arrays are objects, array types are reference types (that is: array variables just hold references to arrays), and this means that an array variable can be null rather than actually pointing to an array:
int[] notAnArray = null;
An empty array is an array of length zero; it has no elements:
int[] emptyArray = new int[0];
(and can never have elements, because an array's length never changes after it's created).
When you create a non-empty array without specifying values for its elements, they default to zero-like values — 0 for an integer array, null for an array of an object type, etc.; so, this:
int[] arrayOfThreeZeroes = new int[3];
is the same as this:
int[] arrayOfThreeZeroes = { 0, 0, 0 };
(though these values can be re-assigned afterward; the array's length cannot change, but its elements can change).
An array has its members initialized to their default values. For int the default is 0. For an Object it's null. A null array is a null Array Reference (since arrays are reference types in Java).
JLS-4.12.5 Initial Values of Variables says in part
For type int, the default value is zero, that is, 0.
and
For all reference types (§4.3), the default value is null.
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).
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.
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
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;
}
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.
You have more going on than you said. I ran the following expanded test from your example:
public class test {
public static void main(String[] args) {
Object[][] someArray = new Object[5][];
someArray[0] = new Object[10];
someArray[1] = null;
someArray[2] = new Object[1];
someArray[3] = null;
someArray[4] = new Object[5];
for (int i=0; i<=someArray.length-1; i++) {
if (someArray[i] != null) {
System.out.println("not null");
} else {
System.out.println("null");
}
}
}
}
and got the expected output:
$ /cygdrive/c/Program\ Files/Java/jdk1.6.0_03/bin/java -cp . test
not null
null
not null
null
not null
Are you possibly trying to check the lengths of someArray[index]?
It does not.
See below. The program you posted runs as supposed.
C:\oreyes\samples\java\arrays>type ArrayNullTest.java
public class ArrayNullTest {
public static void main( String [] args ) {
Object[][] someArray = new Object[5][];
for (int i=0; i<=someArray.length-1; i++) {
if (someArray[i]!=null ) {
System.out.println("It wasn't null");
} else {
System.out.printf("Element at %d was null \n", i );
}
}
}
}
C:\oreyes\samples\java\arrays>javac ArrayNullTest.java
C:\oreyes\samples\java\arrays>java ArrayNullTest
Element at 0 was null
Element at 1 was null
Element at 2 was null
Element at 3 was null
Element at 4 was null
C:\oreyes\samples\java\arrays>
No you can't remove an element from an array, as in making it shorter. Java arrays are fixed-size. You need to use an ArrayList for that.
If you set an element to null, the array will still have the same size, but with a null reference at that point.
// Let's say a = [0,1,2,3,4] (Integer[])
a[2] = null;
// Now a = [0,1,null,3,4]
Yes, you can set elements in an array to null, but code like a[i].equals(a[i+1]) will fail with a NullPointerException if the array contains nulls, so you just have to be more careful if you know that your array may contain nulls. It also doesn't change the size of the array so you will be wasting memory if you remove large numbers of elements. Fixed size arrays are generally not a good way to store data if you are often adding and removing elements - as you can guess from their name.