简体   繁体   中英

filling an bidimensionnal array in java

I'm having some issues filling a bidimensionnal double-array out of a multi-dimensional object-array. My problem is that null value are causing 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) , and i really don't understand why.

What am i doing ? I'm reading a CSV - file, i'm storing the input line by line, in my array of object Data called content . Then i'm filling a double bidimensional array called sortedOutput in which i would like to store LeftSpeed and NormAvgPowOutput which are double value stored in my Data array.

What i want : To have my sortedOutput bidimensionnal array sorted from the smallest to the biggest value on dimension 0 : for variable LeftSpeed .

So how can i avoid the null values? Because when i try to spot them while filling my second array, the compilator says i can't compare a double to a null value.

Sorry for the long post, hope you guys can help me out :) Here my code :

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
}

EDIT : So finally i made 2 huge misstakes. First i tried to sort the array in the loop, that means BEFORE it was fully filled (thanks @Ted Hopp). Secondly i didn't handle the null values correctly. I should have checked if ( a != null , b != null , a[0] != null , b[0] != null ) and then return the new order. (thanks @jboi ).

You are crashing because you are sorting the array sortedOutput before you have read all the entries. The call to Arrays.sort() should be moved to past the loop where you are reading the input.

Alternatively, you can call Arrays.sort() with an expanded argument list to control how much of the array is sorted:

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

However, I see no reason to constantly be sorting after each input.

You also oddly have the check against array elements being null coming after the call to Arrays.sort() which requires them to not be null . If you use the second option, you at least need to move the error checks to before the sort.

As a third alternative, you could explicitly allow for a null array entry inside your comparator. All null entries should sort the same and should always be either before or after non- null entries.

What I see from the stacktace is, that the command Double.compare(a[0], b[0]); is causing the NullPointerException. That means, that one the two is null . What you can to as a quick solution is to change the command with:

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

This can only be quick and dirty as you need to understand WHY there're null, what is in the CSV File, that makes them null and how you handle such data.

So first of all, finally clause is relevant here : you need to invoke the close() method of your stream br there, to avoid any resource leak in case of exceptions.

Secondly, I see no advantage of using arrays instead of list here. In java, we use lists (especially ArrayList in this case) over arrays. Arrays are seldom used, not like in C. Perfs are quite the same (providing you init your list with the same size as you do with your array). Lists are better, because they give you better compile-time check, whereas Arrays only gives runtime-check. For example, the following code compiles without errors:

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

Thirdly, when you have an exception, it is critical that you post here the FULL stacktrace. People will give you better help if they have better information!

Fortunately, here, I can see where the NPE is thrown: Double.compare takes two double as arguments (and not Double). Therefore, your Double are autoboxed to double (google "java autoboxing"), throwing a NPE if they are null. You need to handle the 3 cases of nullity (one is null, the other, and both of them) in your comparator. Alternatively, you can remove null values before sorting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM