简体   繁体   English

对String []数组的数组列表进行排序

[英]Sorting an Array List of String[] arrays

I am reading in a .csv file sort of like a spreadsheet in excel. 我正在阅读.csv文件,有点像excel中的电子表格。 There are a certain number of columns, determined by the file, and I read each line into a string array using the .split(",") method. 有一定数量的列,由文件确定,我使用.split(",")方法将每行读入字符串数组。 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. 但是,当我使用Collections.sort()对数组列表进行排序时,程序会中断。 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. 不要compare的结果乘以-1来反转比较。 Integer.MIN_VALUE * -1 is still Integer.MIN_VALUE . Integer.MIN_VALUE * -1仍然是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. 或者,首先过滤列表以确保所有行都有足够的列。

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

Well, either strings[sortNum] or otherStrings[sortNum] could be out of bounds. 好吧,字符串[sortNum]或otherStrings [sortNum]可能超出范围。 You need to do some checks to prevent that. 您需要进行一些检查以防止这种情况发生。 Also, strings[sortNum] or otherStrings[sortNum] could be null. 此外,字符串[sortNum]或otherStrings [sortNum]可以为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 希望对你有用

I suspect you might have a closure problem in reference to the 'sortNum' variable. 我怀疑你在引用'sortNum'变量时可能有一个闭包问题。 See Jon Skeet's closure article for some guidance, even though it deals with closures in C# it should still be relevant. 请参阅Jon Skeet的封闭文章以获得一些指导,即使它处理C#中的闭包,它仍然应该是相关的。 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));
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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