0

I keep getting a nullpointerexception when I try to sort users where a certain user has a null value in his profile. I was under the impression Google Collection would handle these null values, but it doesnt seem to work.

This is the code I use:

Comparator<UserModel> firstName_comparator = new Comparator<UserModel>() {
    @Override
    public int compare(UserModel c1, UserModel c2) {
        return c1.getProfile().getFirstName().toLowerCase()
                .compareTo(c2.getProfile().getFirstName().toLowerCase());
        }
 };
 Collections.sort(users, Ordering.from(firstName_comparator).nullsLast());

This specific line throws the nullpointerexception:

.compareTo(c2.getProfile().getFirstName().toLowerCase());

Its because getProfile() is null.
How can I fix this? I want to be able to sort my users with null values.

Richard Avalos
  • 555
  • 5
  • 18
  • I dont understand how this is a duplicate to that question. I was asking (maybe not directly) how to fix it (if possible) with Google Collection – Richard Avalos Aug 07 '16 at 14:42

2 Answers2

2

No, Guava won't ignore your NullPointerException. You're providing a Comparator, and this comparator is supposed to respect the Comparator contract. Throwing NullPointerException is not part of the contract.

String firstName1 = c1.getProfile() == null? null : c1.getProfile().getFirstName().toLowerCase();
String firstName2 = c2.getProfile() == null? null : c1.getProfile().getFirstName().toLowerCase();

return Ordering.natural().nullsFirst().compare(firstName1, firstName2);
// or nullsLast(), depending on what you prefer

Or, simpler:

Comparator<UserModel> comparator = 
    Ordering.natural()
            .nullsFirst()
            .onResultOf(model -> c1.getProfile() == null? null : c1.getProfile().getFirstName().toLowerCase());
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • What if `getFirstName()` returns null? – Chetan Kinger Aug 07 '16 at 14:06
  • It will throw an NPE. If firstName can be null, then the OP needs to add yet another null check. – JB Nizet Aug 07 '16 at 14:08
  • Yup. That's precisely the question. Where is the `NullPointerException` coming from. – Chetan Kinger Aug 07 '16 at 14:09
  • No, that's not the question. The OP knows that the NPE is caused by getProfile() returning null. And of course, calling getFirstName() on null causes an NPE. – JB Nizet Aug 07 '16 at 14:09
  • 1
    I feel"Its because getProfile() is null?" was a question rather than a statement. But I guess the question is closed now. – Chetan Kinger Aug 07 '16 at 14:11
  • Thx for the clarification, problem solved! @CKing, in the end it was the firstname that was null, so I changed Jb's code a bit. I had a similar situation where the profile was null, so I assumed it was the same in this case. – Richard Avalos Aug 07 '16 at 14:39
  • @RichardAvalos In that case, I believe you should be accepting my answer :) – Chetan Kinger Aug 07 '16 at 15:39
  • @JBNizet I guess I was right about the question being about the source of the`NullPointerException` after all ;) – Chetan Kinger Aug 07 '16 at 15:40
  • Just out of curiousity, how come your 2nd solution still returns a NPE? Comparator comparator = Ordering.natural().nullsFirst() .onResultOf((UserModel c1) -> c1.getProfile() == null ? null : c1.getProfile().getFirstName().toLowerCase()); Collections.sort(users, comparator); – Richard Avalos Aug 07 '16 at 16:17
  • @RichardAvalos Because getFirstName() returns null and you're still calling toLowerCase() on it? Have you read http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it? Because that seems to be the crux of your question: you don't seem to understand what an NPE is. – JB Nizet Aug 07 '16 at 16:20
  • bleh, i feel so dumb for not doing a null check on firstname instead of profile. Thx for waking me up! – Richard Avalos Aug 07 '16 at 16:28
1

I was under the impression Google Collection would handle these null values

The nullLast method will only check if a particular element in the collection is null and place it at the end of the collection.

This specific line throws the nullpointerexception:

.compareTo(c2.getProfile().getFirstName().toLowerCase());

There are two possibilities for nulls here :

  1. c2.getProfile() is null
  2. c2.getProfile().getFirstName() is null

You need to explicitly safeguard your Comparator implementation from these nulls.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82