Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort an array of objects containing null elements?

In my program an array fClasses of fixed length [7] of objects is created, each object is a class FClass that contains 3 Strings, an int, and an int[]. These values are read from a .txt file and added to a specific index of the array based on the value of the int. There are less entries in the .txt file then there are indices in the array so the array ends up looking something like this:

fClasses[0] { str1, str2, str3, int1, int [] {1,2,3,4,5}}
fClasses[1] { str1, str2, str3, int1, int [] {1,2,3,4,5}}
fClasses[2] { str1, str2, str3, int1, int [] {1,2,3,4,5}}
fClasses[3] null
fClasses[4] null
fClasses[5] { str1, str2, str3, int1, int [] {1,2,3,4,5}}
fClasses[6] { str1, str2, str3, int1, int [] {1,2,3,4,5}}

Later in the program I need to sort the array based on the average of the ints in the int[]. I have a working method to return this but when I try to sort the array using compareTo and Arrays.sort I get a long list of errors starting with these:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
    at java.util.ComparableTimSort.sort(Unknown Source)
    at java.util.Arrays.sort(Unknown Source)
    at FProg.sortClasses(FProg.java:228)

My compareTo method looks like this and it's located in a class that implements Comparable:

public int compareTo(FClass other) 
{
    if (other == null || this.avg == other.avg)
    {
        return 0;
    }
    else if (this.avg < other.avg)
    {
        return -1;
    }
    else
    {
        return 1;
    }

}

And I'm trying to call this method to do the sorting:

public void sortClasses()
{
    Arrays.sort(fClasses, 0, MAX_CLASSES);
}

I have tested it with a .txt file that contains enough entries to fill the array and the sort works correctly in that case, so I believe the problem I'm having is that my sort method can't sort an array with null elements in it. Is there any way this can be achieved?

like image 326
FergusMacNamara Avatar asked Dec 18 '14 21:12

FergusMacNamara


2 Answers

Using Java 8, you can easily build the comparator you need:

Arrays.sort(fClasses, Comparator.nullsFirst(Comparator.naturalOrder()));

Use nullsLast instead if that's what you want, of course.

like image 175
Jeffrey Bosboom Avatar answered Oct 17 '22 00:10

Jeffrey Bosboom


You need your own Comparator implementation and check for nulls and return 0

 Arrays.sort(fClasses, new Comparator<FClass>() {
    @Override
    public int compare(FClass o1, FClass o2) {
        if (o1 == null && o2 == null) {
            return 0;
        }
        if (o1 == null) {
            return 1;
        }
        if (o2 == null) {
            return -1;
        }
        return o1.compareTo(o2);
    }});
like image 25
Subin Sebastian Avatar answered Oct 17 '22 01:10

Subin Sebastian