无法读取字段 "value",因为 "anotherByte" 为空

Cannot read field "value" because "anotherByte" is null

这里我有一个快速排序算法。基数 class 具有函数 isLessThan()

abstract public class Sort<T extends Comparable<T>> {
    
    protected T[] array;

    public boolean isLessThan(T obj1, T obj2) {
        if (obj1.compareTo(obj2) < 0)
            return true;
        else
            return false;
    }
    
    abstract public void sort(T[] array);
}

实际算法选择一个分区,将数组拆分为高、低数组,然后递归地对高数组和低数组进行分区。但是我无法通过向高和低添加元素的部分:

public class Quick<T extends Comparable<T>> extends Sort<T> {
    T[] low, high;
    
    public void addLow(T element, int index) {
        low[index] = element;
    }
    public void addHigh(T element, int index) {
        high[index] = element;
    }
    
    public T[] partition(T[] arr, T partition) {
        int lowCount = 0;
        int highCount = 0;
        
        low = (T[]) new Comparable[arr.length];
        high = (T[]) new Comparable[arr.length];
        // here I am adding each element to either high or low
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] != null) {
                if (isLessThan(arr[i], partition)) {
                    addLow(arr[i], i);
                    lowCount++;
                } else {
                    addHigh(arr[i], i);
                    highCount++;
                }
                
            }
        }
        // the rest of this code probably isn't relevant to my problem
        // sort low, then high
        if (lowCount > 1) {
            low = partition(low, low[0]);

        }
        if (highCount > 1) {
            high = partition(high, high[0]);
        }

        // merge
        T[] arr2 = (T[]) new Comparable[low.length + high.length];
        int count = 0;
        for(int i = 0; i < low.length; i++) { 
            arr2[i] = low[i];
             count++;
          } 
          for(int j = 0; j < high.length;j++) { 
              arr2[count++] = high[j];
          } 
        
        
        return arr2;
    }
    
    public void sort(T[] arr)
    {
        T partition = arr[0];
        
        arr = partition(arr, partition);
        
        
        
        //set super to array
        super.array = arr;
        
    }
}

出于某种原因,调用 isLessThan() 时出现此错误:

Exception in thread "main" java.lang.NullPointerException: Cannot read field "value" because "anotherByte" is null
    at java.base/java.lang.Byte.compareTo(Byte.java:490)
    at java.base/java.lang.Byte.compareTo(Byte.java:56)
    at Sort.isLessThan(Sort.java:6)
    at Quick.partition(Quick.java:20)
    at Quick.partition(Quick.java:33)
    at Quick.sort(Quick.java:59)
    at Main.main(Main.java:7)

导致此错误的原因是什么?

我的主图是这样的:

public class Main {

    public static void main(String[] args) {
        Byte[] array = {121, 25, 44, 17, 30, 55, 29, 7, 81, 45, 79, 41, 108, 60, 83, 29, 77, 5, 17, 110};

        Quick s = new Quick();
        s.sort(array);
    }

}

您的假设 此代码的其余部分可能与我的问题无关 是错误的。因为low[0]确实是null

    // the rest of this code probably isn't relevant to my problem
    // sort low, then high
    if (lowCount > 1) {
        System.out.println("LOW: " + low[0]);
        low = processPartition(low, low[0]);
    }
    
    if (highCount > 1) {
        System.out.println("HIGH: " + high[0]);
        high = processPartition(high, high[0]);
    }

您实例化了两个数组并说它们与原始数组具有相同的维度。这个没问题。

    low = (T[]) new Comparable[arr.length];
    high = (T[]) new Comparable[arr.length];

但是你的错误是,你使用了错误的索引方法!您从 for 循环中获取索引并将其作为索引传递给数组。

for (int i = 0; i < arr.length; i++) {
   if (arr[i] != null) {
      if (isLessThan(arr[i], partition)) {
          addLow(arr[i], i);
          lowCount++;
      } else {
           addHigh(arr[i], i);
           highCount++;
      }
 }

但是会发生什么?

通过第一次比较,121 上有 121。这不小于但等于。在 更高或等于 的情况下,您进入 else-part 并调用 addHigh().

所以索引 0 没有高。

现在比较继续进行,所有其他人都是 LessThan() 因为 121 是您列表中的最高数字。

但是,当您从循环中提交索引时,第一个 LessThan() 值不会进入 low[0],而是进入 low[1]low[0]null!

然后你稍后打电话给 low = processPartition(low, low[0]); 并获得你的 NPE。

所以你至少有 1 件事要做:

不要在 for 循环中使用 索引 i!错了!

请使用 您的计数器 lowCounthighCount!它们将始终指向数组中的正确字段!

请注意,这只会解释为什么你在这里得到第一个NPE并帮助你解决它。

当您 运行 此代码时,将出现相同的 NPE 消息,但发生在过程的另一点。这一次,因为您总是传递数组并不断更改它们。当代码有时回到第一轮并继续进行时,它将找到 highCount > 1 并尝试处理 high[] 数组。但这同时发生了变化,high[0] 为空。

你必须重新考虑这里的整个排序方法。

我希望这至少有助于找出问题所在。