开发者

Sorting an Array List of String[] arrays

开发者 https://www.devze.com 2023-04-03 04:58 出处:网络
I am reading in a .csv file sort of like a spreadsheet in excel. There are a certain number of columns, determined by the file, and I read each line into a stri开发者_如何转开发ng array using the .spl

I am reading in a .csv file sort of like a spreadsheet in excel. There are a certain number of columns, determined by the file, and I read each line into a stri开发者_如何转开发ng array using the .split(",") method. I then put this into an array list so it can hold all of the string arrays without giving it a specific size. However, when I go to sort the array list using Collections.sort(), the program breaks. What could the problem be? Here is my code to sort:

Collections.sort(stringList, new Comparator < String[] > () {
    public int compare(String[] strings, String[] otherStrings) {
        return -1 * (strings[sortNum].compareTo(otherStrings[sortNum]));
    }
});


Two points:

  • Don't multiply the result of compare by -1 to reverse a comparison. Integer.MIN_VALUE * -1 is still Integer.MIN_VALUE. Instead, reverse the order of the comparison itself
  • My guess is that you've actually got some rows without enough columns. Perhaps you should put those at the end?

Something like:

Collections.sort(stringList, new Comparator < String[] > () {
    public int compare(String[] x1, String[] x2) {
        if (x1.length > sortNum && x2.length > sortNum) {
            return x2[sortNum].compareTo(x1[sortNum]); 
        }
        if (x1.length > sortNum) {
            return 1;
        }
        if (x2.length > sortNum) {
            return -1;
        }
        return x2.length - x1.length;
    }
});

Alternatively, filter your list first to make absolutely sure that all rows have enough columns.


Well, either strings[sortNum] or otherStrings[sortNum] could be out of bounds. You need to do some checks to prevent that. Also, strings[sortNum] or otherStrings[sortNum] could be null. I bet you're running into one of these 2 things. What does the call stack indicate?


Try using this

First your class comparator with a constructor:

public class MyStringArrayComparator implements Comparator<String[]>{

       Integer sortNum;

       public MyStringComparator(Integer index) {
              sortNum = index;
       }

       @Override
       public int compare(String[] strings, String[] otherStrings) {
              return -1*(strings[sortNum].compareTo(otherStrings[sortNum]));
       }
}

and in your code

Collections.sort(stringList,new MyStringArrayComparator<String[]>(index));

Hope that works for you


Sharing code in case someone need to do the sort on multiple columns.

public final class ArrayComparatorWithIndex<T extends Comparable<T>> implements Comparator<T[]>
{
    private final int[] indexToSort;

    public ArrayComparatorWithIndex(int[] indexToSort)
    {         
        if(indexToSort == null || indexToSort.length == 0){
            throw new IllegalArgumentException("Index to use for sorting cannot be null or empty.");
        }
        this.indexToSort = indexToSort;
    }

    @Override
    public int compare(T[] str, T[] otherStr)
    { 
        int result= 0;
        for (int index : indexToSort)
        {
            result= str[index].compareTo(otherStr[index]);
            if (result != 0){
                break;
            }
        }
        return result;
    }
}

//Example how to use it:  
int[] indexForSorting= new int[] { 1, 3 };
Collections.sort(stringList, new ArrayComparatorWithIndex<String>(indexForSorting));


I suspect you might have a closure problem in reference to the 'sortNum' variable. See Jon Skeet's closure article for some guidance, even though it deals with closures in C# it should still be relevant. Even if you don't have this issue, it's a good read. :)


you can provide default values for empty "cells":

            public int compare(String[] strings, String[] otherStrings) {
                String one, other;
                one = other = ""; // default value
                if (sortNum<strings.length && strings[sortNum] != null) {
                    one = strings[sortNum];
                }
                if (sortNum<otherStrings.length && otherStrings[sortNum] != null) {
                    other = otherStrings[sortNum];
                }
                return -1 * (one.compareTo(other));
            }
0

精彩评论

暂无评论...
验证码 换一张
取 消