views:

224

answers:

7

I trying to find whether the elements of 2 arrayLists are match or not. But this code give me error Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException since some of the elements are null.

How can I solved this problem?

String level []={"High","High","High","High","High","High"};
ArrayList<Object> n = new ArrayList<Object>(Arrays.asList(level));

String choice []={null,"High","Low","High",null,"Medium"}; 
ArrayList<Object> m = new ArrayList<Object>(Arrays.asList(choice));

//Check if the two arrayList are identical
for(int i=0; i<m.size(); i++){
   if(!(m.get(i).equals(n.get(i)))){   
 result= true;
 break;
   } 
} 
    return  result;
}
+4  A: 

The problem is that you are calling the equals method on some elements without first checking for null.

Change to:

for(int i=0; i<m.size(); i++){
   if(m.get(i) != null && !(m.get(i).equals(n.get(i)))){   
     result = true;
     break;
   } 
} 

Or if you want to allow two null values to compare equal:

for(int i=0; i<m.size(); i++){
   if (m.get(i) == null) {
     if (n.get(i) != null) {
       result = true;
     }
   } else if(!(m.get(i).equals(n.get(i)))){   
     result = true;
   } 
   if (result) {
     break;
   }
} 

One thing I don't get - why are you setting result to true when you find a mismatch? Don't you want to return true if both lists match and false otherwise?

danben
Should check if m and n are both null and set result to true if so.
Jason Hall
Yep, was adding that when I realized he might want to allow it. Thanks though.
danben
Might want to cache that first `m.get(i)`, the JIT may not realize it can rely on it not having changed between the two retrievals. (And in fact, without knowing the OP's code better, we don't know that either! :-) )
T.J. Crowder
@T.J. Crowder: I thought of that while I was typing but didn't think it would add much in the context of the question. Still, a valid point.
danben
Thank you very much. Yes I want to allow null. Thank you, Thank you,Thank you :-)
Jessy
There's a typo with result == true;
Justin Ardini
@Jessy if you want to "allow nulls" use `enum`. You never nulls to represent a valid value
Pyrolistical
@Justin Ardini: fixed, thanks.
danben
A: 

if you know the first list never contains nulls switch the call around

if(!(n.get(i).equals(m.get(i)))){ 

also specifying ArrayList<Object> is bad practice, use List<String> if it is actually String objects.

fuzzy lollipop
A: 

Rewrite your if like this in order to check for both double-nullity and single-nullity:

if((m.get(i) == null && n.get(i) == null) || (m.get(i) != null && !(m.get(i).equals(n.get(i)))))
Dan Story
+1  A: 

The root of this problem could be you are using null as an actual value.

Just looking at your code you could use enum and instead of null use an EMPTY value. Then you can actually compare with in a list without nullpointerexceptions.

Check this out: http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html

Also try to avoid using arrays. Just use List but use the proper type. Don't use List<Object> that is almost never valid.

null should indicate an error or testing only. It should never be used in valid code as you will create null pointer exception bugs during runtime.

Pyrolistical
+8  A: 

Just use Arrays.equals, like so:

    String level []={"High","High","High","High","High","High"};

    String choice []={null,"High","Low","High",null,"Medium"}; 

    return Arrays.equals(level, choice); 
derivation
While this can be a solution, I would discourage the use of Arrays to a newbie. Everybody should use List whenever possible
Pyrolistical
(@OP: In `java.util`, in case you were wondering.)
T.J. Crowder
@Pyrolistical - I agree Lists should be used whenever possible. But since the OP had the 'lists' in arrays originally it seemed like a waste to convert when a standard util function did what is needed.
derivation
@derivation You solved his immediate problem, but I say you have to go a step further and try to understand what the root of the problem is. The real problem here is he is using arrays instead of List. We should try to teach them more than just solving their problem
Pyrolistical
+1  A: 

Check if the objects are the same object (or both null) first. Check for null before you do the equals() test.

    boolean result = true;
    String level[] = { "High", "High", "High", "High", "High", "High" };
    ArrayList<String> n = new ArrayList<String>(Arrays.asList(level));

    String choice[] = { null, "High", "Low", "High", null, "Medium" };
    ArrayList<String> m = new ArrayList<String>(Arrays.asList(choice));

    // Check if the two arrayList are identical
    for (int i = 0; i < m.size(); i++) {
      String mElement = m.get(i);
      String nElement = n.get(i);

      if (mElement == nElement) {
        result = true;
      } else if ((mElement == null) || (nElement == null)) {
        result = false;
        break;
      } else if (!(m.get(i).equals(n.get(i)))) {
        result = false;
        break;
      }
    }

    return result;
  }
Rob Heiser
A: 

Rather than solving this specific problem, give yourself a tool you can use over and again, e.g.:

public static final boolean areEqual(Object o1, Object o2) {
    return o1 == null ? o2 == null : o1.equals(o2);
}

...in some handy utility class, then use that in your loop.

But of course, for this specific requirement, derivation has the right answer (use java.util.Arrays.equals(Object[],Object[])).

T.J. Crowder