代码之家  ›  专栏  ›  技术社区  ›  Dylan Warcholik

为什么我的字符串[]的ArrayList排序不正确?

  •  -1
  • Dylan Warcholik  · 技术社区  · 2 年前

    我正在从一个文件中读取数据,并询问用户他们想按哪个类别排序。该文件有13列(从国家、年份和大陆开始,然后是我暂时忽略的双重统计数据列表)和792行。我在初始化ArrayList<字符串[]>,我有一种方法可以打印出这些行,并且它们的格式正确。

    我正试图根据其中一列对ArrayList进行排序(我现在使用第一列,因为比较国家名称是最容易看到的,而且原始文件已经按年份组织好了,所以这不是判断排序是否有效的好方法)。我目前正在尝试实现一个selectionSort方法,该方法似乎可以正常工作,但当我打印出修改后的ArrayList的行时,有几行出现了问题(但似乎许多部分组织得更好)。

    以下是文件中的几行,供转换为String[]时参考:

    [新加坡2015 AS 6.572000027 1.69227767 1.353814363 0.949492395 0.549840569 0.345965981 0.464307785 85]

    [荷兰2015年欧盟7.376999855 1.5039444635 1.428939223 0.810696125 0.585384488 0.47048983 0.282661825 84]

    [加拿大2015 NA 7.315999985 1.479204416 1.481348991 0.834557652 0.611100912 0.435539722 0.287371516 83]

    以下是我遇到问题的selectionSort方法的代码块。 数组列表<字符串[]>data是要读入的数据,Country示例的int sortIndex为零,这是我试图比较的每个String[]的列。

    public static void selectionSort(ArrayList<String[]> data, int sortIndex){
        int i;
        int j;
        String[] temp;
        int indexSmallest = 0;
    
        for (i = 0; i < data.size()-1; i++) {
            indexSmallest = i;
                
            for (j= i + 1; j < data.size(); j++) {
                if (data.get(j)[sortIndex].compareTo(data.get(i)[sortIndex]) < 0) {
                    indexSmallest = j;
                }
            }
            temp = data.get(i);
            data.set(i, data.get(indexSmallest));
            data.set(indexSmallest, temp);
        }
    }
    

    我是堆栈溢出的新手,所以如果有任何额外的信息我应该包括在内,请让我知道!我读过几个类似的问题,但一直没能弄清楚我的过程出了什么问题。提前感谢!

    更新: 以下是我对ArrayList的初始化,在我的主方法中称为dataAL:

    while (currLine != null) {
        dataAL.add(currLine.split("\\,", -1));
        lineNum++;
        currLine = readBuffer.readLine();
    }
    

    我用一个单独的printRow(String[]row)方法输出数组,该方法只打印传递给该方法的每一行,每行用空格分隔,两端用硬括号(如我上面列出的示例行所示)。ArrayList<字符串[]>被称为dataAL,但当传递给排序方法时,它被命名为data,然后再次作为数据传递给插入排序方法。以下是数据的打印:

    for (int k = 0; k < data.size(); k++){
        printRow(data.get(k));
    }
    

    我希望当这些行打印出来时,这些行是按照每个String[]的索引0的字母顺序组织的,这是我正在比较的国家名称,虽然有些部分是按字母顺序排列的,但整个列表不是。

    1 回复  |  直到 2 年前
        1
  •  1
  •   Reilas    2 年前

    “…我正在从一个文件中读取数据,并询问用户他们想按哪个类别排序。该文件有13列(从国家、年份和大陆开始,然后是一个双重统计列表……”

    这里的一个简单解决方案是使用 class ,以包含每个条目。

    下面是一个例子。

    class Entry {
        String country, continent;
        int year, h;
        double a, b, c, d, e, f, g;
    
        static Entry parse(String s) {
            Entry e = new Entry();
            String[] a = s.split(" ");
            e.country = a[0];
            e.year = Integer.parseInt(a[1]);
            e.continent = a[2];
            e.a = Double.parseDouble(a[3]);
            e.b = Double.parseDouble(a[4]);
            e.c = Double.parseDouble(a[5]);
            e.d = Double.parseDouble(a[6]);
            e.e = Double.parseDouble(a[7]);
            e.f = Double.parseDouble(a[8]);
            e.g = Double.parseDouble(a[9]);
            e.h = Integer.parseInt(a[10]);
            return e;
        }
    }
    

    这将使解析更加符合流。

    String s
        = "Singapore 2015 AS 6.572000027 1.69227767 1.353814363 0.949492395 0.549840569 0.345965981 0.464307785 85\n"
        + "Netherlands 2015 EU 7.376999855 1.503944635 1.428939223 0.810696125 0.585384488 0.47048983 0.282661825 84\n"
        + "Canada 2015 NA 7.315999985 1.479204416 1.481348991 0.834557652 0.611100912 0.435539722 0.287371516 83";
    List<Entry> l = new ArrayList<>();
    try (Scanner t = new Scanner(s)) {
        while (t.hasNext()) l.add(Entry.parse(t.nextLine()));
    }
    

    并且,从这里您可以利用 List#sort 方法,以比较特定 field 属于 进入 ;如果允许的话 “可比较”

    l.sort(Comparator.comparing(a -> a.country));
    
    [{'Canada', 2015, 'NA', ... }, {'Netherlands', 2015, 'EU', ... }, {'Singapore', 2015, 'AS', ... }]
    
        2
  •  0
  •   Eritrean    2 年前

    不要把事情搞得不必要的复杂化。您可以使用的排序方法 List ,它接受一个比较器:

    public static void main(String[] args) {
        List<String[]> myList = new ArrayList<>();
        myList.add(new String[] {"Singapore", "2015", "AS", "6.572000027", "1.69227767", "1.353814363", "0.949492395",
                                 "0.549840569", "0.345965981", "0.464307785", "85"});
        myList.add(new String[] {"Netherlands", "2015", "EU", "7.376999855", "1.503944635", "1.428939223", "0.810696125",
                              "0.585384488", "0.47048983", "0.282661825", "84"});
        myList.add(new String[] {"Canada", "2015", "NA", "7.315999985", "1.479204416", "1.481348991", "0.834557652",
                                 "0.611100912", "0.435539722", "0.287371516", "83"});
    
        System.out.println("Before sorting");
        myList.forEach(arr -> System.out.println(Arrays.toString(arr)));
        
        sortByIndex(myList, 0);
    
        System.out.println("After sorting");
        myList.forEach(arr -> System.out.println(Arrays.toString(arr)));
    }
    
    public static void sortByIndex(List<String[]> data, int sortIndex) {
        data.sort(Comparator.comparing(d -> d[sortIndex]));
    }
    

    当然,您可能需要事先检查索引是否有效。