Подтвердить что ты не робот

Как отсортировать массив объектов, содержащих нулевые элементы?

В моей программе создается массив fClasses фиксированной длины [7] объектов, каждый объект представляет собой класс FClass, который содержит 3 Strings, int и int[]. Эти значения считываются из TXT файла и добавляются к определенному индексу массива на основе значения int. В файле .txt меньше записей, тогда в массиве есть индексы, поэтому массив заканчивается тем, что выглядит примерно так:

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}}

Позже в программе мне нужно отсортировать массив на основе среднего значения ints в int[]. У меня есть рабочий метод, чтобы вернуть это, но когда я пытаюсь сортировать массив с помощью compareTo и Arrays.sort, я получаю длинный список ошибок, начиная с них:

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)

Мой метод compareTo выглядит так и находится в классе, который реализует 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;
    }

}

И я пытаюсь вызвать этот метод для сортировки:

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

Я тестировал его с .txt файлом, который содержит достаточно записей для заполнения массива, и сортировка работает правильно в этом случае, поэтому я считаю, что проблема, с которой я столкнулась, заключается в том, что мой метод сортировки не может сортировать массив с нулевые элементы в нем. Есть ли способ, которым это может быть достигнуто?

4b9b3361

Ответ 1

Вам понадобится ваша собственная реализация Comparator и проверьте нули и верните 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);
    }});

Ответ 2

Используя Java 8, вы можете легко построить необходимый компаратор:

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

Используйте nullsLast, если это то, что вы хотите, конечно.

Ответ 3

Вам нужно создать Comparator<FClass>, а не использовать Comparable<FClass>.

public class FClassComparator implements Comparator<FClass> 
{
    public int compare(FClass left, FClass right) {
        // Swap -1 and 1 here if you want nulls to move to the front.
        if (left == null) return right == null ? 0 : 1;
        if (right == null) return -1;
        // you are now guaranteed that neither left nor right are null.

        // I'm assuming avg is int. There is also Double.compare if they aren't.
        return Integer.compare(left.avg, right.avg); 
    }
}

Затем вызовите сортировку через:

Arrays.sort(fClassArray, new FClassComparator());

Ответ 4

С Apache Commons Collections 4 вы можете использовать ComparatorUtils для этого:

Collections.sort(arr, ComparatorUtils.nullLowComparator(ComparatorUtils.NATURAL_COMPARATOR));