如何对包含null元素的对象数组进行排序?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何对包含null元素的对象数组进行排序?相关的知识,希望对你有一定的参考价值。
在我的程序中,创建了一个固定长度[7]的对象的数组fClasses
,每个对象是一个类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文件测试了它,该文件包含足够的条目来填充数组,并且在这种情况下排序正常工作,所以我相信我遇到的问题是我的排序方法无法对具有null元素的数组进行排序它。有什么办法可以实现吗?
您需要自己的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);
}});
使用Java 8,您可以轻松构建所需的比较器:
Arrays.sort(fClasses, Comparator.nullsFirst(Comparator.naturalOrder()));
当然,如果那是你想要的,请使用nullsLast
。
你必须创建一个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);
}
}
然后调用sort via:
Arrays.sort(fClassArray, new FClassComparator());
使用Apache Commons Collections 4你可以使用ComparatorUtils来做到这一点:
Collections.sort(arr, ComparatorUtils.nullLowComparator(ComparatorUtils.NATURAL_COMPARATOR));
通过导入org.apache.commons.collections.comparators库的Apache 2.1.1 Release包,我可以使用ArrayList<String>
作为NullComparator
方法的第二个参数对列表进行排序,例如Collections.sort()
,如下所示:
ArrayList<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
list.add("baz");
list.add(null);
// Sort the list
Collections.sort(list, new NullComparator(true));
System.out.println(list);
// outputs:
// [bar, baz, foo, null]
我喜欢这种方法的是NullComparator
有一个重载构造函数,它允许你指定是否要将null
视为高值或低值,这对我来说似乎非常直观。
NullComparator(boolean nullsAreHigh)
希望这有助于某人!
以上是关于如何对包含null元素的对象数组进行排序?的主要内容,如果未能解决你的问题,请参考以下文章