【问题标题】:How to sort an array of objects containing null elements?如何对包含空元素的对象数组进行排序?
【发布时间】:2015-02-17 19:15:38
【问题描述】:

在我的程序中,创建了一个固定长度 [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}}

稍后在程序中,我需要根据int[] 中的ints 的平均值对数组进行排序。我有一个工作方法来返回它,但是当我尝试使用 compareToArrays.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 文件对其进行了测试,并且在这种情况下排序工作正常,所以我相信我遇到的问题是我的排序方法无法对数组进行排序其中的空元素。有什么办法可以实现吗?

【问题讨论】:

    标签: java arrays sorting compareto


    【解决方案1】:

    使用 Java 8,您可以轻松构建所需的比较器:

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

    当然,如果这是您想要的,请使用 nullsLast

    【讨论】:

      【解决方案2】:

      您需要自己的 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);
          }});
      

      【讨论】:

      • 不应该 o1 == null 返回 -1,因为 null 值意味着它的重要性低于实际有值的 o2
      【解决方案3】:

      您必须创建一个Comparator&lt;FClass&gt;,而不是使用Comparable&lt;FClass&gt;

      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));
        

        【讨论】:

          【解决方案5】:

          通过导入org.apache.commons.collections.comparatorsApache 2.1.1 Release 库,我可以使用NullComparator 作为Collections.sort() 方法的第二个参数对列表进行排序,例如ArrayList&lt;String&gt;,如下所示:

          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)
          

          希望这对某人有所帮助!

          【讨论】:

            猜你喜欢
            • 2016-04-27
            • 2011-03-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-13
            • 2010-09-18
            • 1970-01-01
            相关资源
            最近更新 更多