1

我在从多维对象数组中填充双向双数组时遇到了一些问题。我的问题是 null 值导致 a java.lang.NullPointerException at IOControl.ReadCSV$1.compare(ReadCSV.java:328) at IOControl.ReadCSV$1.compare(ReadCSV.java:1) at java.util.TimSort.countRunAndMakeAscending(Unknown Source) at java.util.TimSort.sort(Unknown Source) at java.util.TimSort.sort(Unknown Source) at java.util.Arrays.sort(Unknown Source) at IOControl.ReadCSV.run(ReadCSV.java:324) at en.window.Main.main(Main.java:46),我真的不明白为什么。

我在做什么 ? 我正在读取一个 CSV 文件,我将输入逐行存储在我的对象数组中,Data称为content. 然后我正在填充一个double名为的二维数组sortedOutput,我想在其中存储它LeftSpeedNormAvgPowOutput它们是存储在我的Data数组中的双精度值。

我想要什么: 让我的sortedOutput双向数组在维度 0 上从最小值到最大值排序:对于变量LeftSpeed

那么我怎样才能避免空值呢?因为当我在填充第二个数组时尝试发现它们时,编译器说我无法将双精度值与null值进行比较。

很抱歉,这篇文章很长,希望你们能帮助我:)这是我的代码:

public void run(String path, int length) 
{
/* 
* Main function of ReadCSV class.
 * Open / reads / closes the file.
 * Fills the object.
 */

  BufferedReader br = null;
  String input = "";
  String cvsSplitBy = ",";
  int[] pos = new int[200];

  Data[] content = new Data[length];
  Double[][] sortedOutput = new Double[length][4];
  int i = 0;
  int j = 0;
  int k = 0;

  try 
  {
    br = new BufferedReader(new FileReader(path));
    while ((input = br.readLine()) != null) 
     {
       // use comma as separator
       String[] lines = input.split(cvsSplitBy);
       content[i] = new Data(); 
       if (i == 0)
       {
         //not relevant here                
       }
       else
       {
        j = 0;
        content[i].setTime("TIME", getTime(pos[j++], lines));
        content[i].setData("DATA", getContent(pos[j++], lines));
        //etc
       }
       // gets rid of non coherent or useless values, e.g negative power, ...
       if (content[i].lhWdStdev > 0 && content[i].rhWdStdev > 0)
       {
        normalizeData(content[i]); // not relevant
        content[k].setLeftSpeed();
        sortedOutput[k][0] = content[k].getLeftSpeed();
        sortedOutput[k][2] = content[k].getNormAvgPowOutput();
        Arrays.sort(sortedOutput, new java.util.Comparator<Double[]>()
        {
           public int compare(Double[]a, Double[]b)
           {
             return Double.compare(a[0], b[0]);
            }
         });
   }
   if (sortedOutput[k][0] == null)
   {
     System.out.println("FAIL");
   }
   System.out.println("Output = " +sortedOutput[k][0]);
   i++;
   k++;
 }
} 
catch (FileNotFoundException e) 
  {
    e.printStackTrace();
  } 
catch (IOException e) 
  {
    e.printStackTrace();
  } 
finally 
  {
  // Again it's not relevant
}

编辑:所以最后我犯了两个巨大的错误。首先,我尝试在循环中对数组进行排序,这意味着在它完全填充之前(感谢@Ted Hopp)。其次,我没有null正确处理这些值。我应该检查 if ( a != null, b != null, a[0] != null, b[0] != null) 然后返回新订单。(感谢@jboi)。

4

3 回答 3

2

您正在崩溃,因为您在sortedOutput阅读所有条目之前对数组进行排序。Arrays.sort()应将调用移至您正在读取输入的循环之后。

或者,您可以Arrays.sort()使用扩展的参数列表调用来控制数组的排序量:

Arrays.sort(sortedOutput, 0, k + 1, new java.util.Comparator<Double[]>()
    {
       public int compare(Double[]a, Double[]b)
       {
         return Double.compare(a[0], b[0]);
        }
     });

但是,我认为没有理由在每次输入后不断进行排序。

奇怪的是,您还可以检查数组元素是否null在调用后出现Arrays.sort(),要求它们不是null。如果您使用第二个选项,您至少需要将错误检查移到排序之前。

作为第三种选择,您可以明确允许null比较器内的数组条目。所有条目都应排序相同,并且应始终位于非条目null之前或之后。null

于 2013-09-12T12:33:56.443 回答
1

我从堆栈中看到的是,该命令Double.compare(a[0], b[0]);导致 NullPointerException。这意味着,一个两个是null。作为一个快速解决方案,您可以使用以下命令更改命令:

Double.compare((a[0]==null)? Double.NaN:a[0], (b[0]==null)? Double.NaN:b[0]);

这只能是快速和肮脏的,因为您需要了解为什么有 null、CSV 文件中的内容、使它们为 null 以及您如何处理此类数据。

于 2013-09-12T12:45:39.520 回答
0

所以首先,finally 子句在这里是相关的:您需要在那里调用流 br 的 close() 方法,以避免在发生异常时发生任何资源泄漏。

其次,我认为在这里使用数组而不是列表没有任何优势。在 java 中,我们在数组上使用列表(在这种情况下尤其是 ArrayList)。数组很少使用,不像在 C 中那样。Perfs 是完全一样的(如果你初始化你的列表的大小与你对数组的大小相同)。列表更好,因为它们为您提供更好的编译时检查,而数组仅提供运行时检查。例如,下面的代码编译没有错误:

String[] strings = new String[1];
Object[] objects = strings;
objects[0] = new Integer(1); 

第三,当您遇到异常时,在此处发布完整的堆栈跟踪至关重要。如果他们有更好的信息,人们会给你更好的帮助!

幸运的是,在这里,我可以看到抛出 NPE 的位置:Double.compare 将两个 double 作为参数(而不是 Double)。因此,您的 Double 被自动装箱为双倍(谷歌“java autoboxing”),如果它们为空则抛出 NPE。您需要在比较器中处理 3 种无效情况(一种为 null,另一种为 null,另一种为 null)。或者,您可以在排序之前删除空值。

于 2013-09-12T12:28:50.180 回答