Как отсортировать массив объектов, содержащих нулевые элементы?
В моей программе создается массив 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 файлом, который содержит достаточно записей для заполнения массива, и сортировка работает правильно в этом случае, поэтому я считаю, что проблема, с которой я столкнулась, заключается в том, что мой метод сортировки не может сортировать массив с нулевые элементы в нем. Есть ли способ, которым это может быть достигнуто?
Ответы
Ответ 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));