【问题标题】:Java sort 2D String Array by number value of third columnJava按第三列的数值对二维字符串数组进行排序
【发布时间】:2015-10-13 22:16:51
【问题描述】:

我收到了一个包含国家、姓名和滑冰选手分数的文本文件。我必须将每一行读入一个数组,然后按降序对数组进行排序。

我设法把所有的东西都整理成这样:

infoArray[0][0] = "GER";
infoArray[0][1] = "Nathalie WEINZIERL Maylin & Daniel Peter LIEBERS Nelli & Alexander";
infoArray[0][2] = "17.0";

infoArray[1][0] = "RUS";
infoArray[1][1] = "Evgeny PLYUSHCHENKO Tatiana & Maxim Yulia LIPNITSKAYA Ekaterina & Dmitri"
infoArray[1][2] = "37.0";

infoArray[2][0] = "CHN";
infoArray[2][1] = "Kexin ZHANG Han YAN Cheng & Hao Xintong & Xun"
infoArray[2][2] = "20.0"

等等 10 个不同的国家。

我现在需要的是使用第三列按降序显示 10 个不同的国家,这是数值(尽管它是字符串格式)。

所以换句话说,我希望这三个国家的产出是:

RUS: 37.0
CHN: 20.0
GER: 17.0

我考虑过使用嵌套循环,但不能完全理解如何让它发挥作用。

【问题讨论】:

  • Java 是一种面向对象的编程语言。您应该首先创建一个类,然后拥有所有这些实例的单个数组。那么排序只是实现正确的比较器的问题,你会发现如何去做没有问题(已经有很多例子了)。
  • 您能否详细说明“首先创建一个类,然后拥有所有这些实例的单个数组”的含义?
  • 什么@AlexisC。意味着您有一个包含不同类型数据的多维数组。所以基本上,数组的每一行都会存储一些属于同一项目的属性。在 Java 中,您可以通过创建代表某个实体的适当类来完成您正在做的事情。然后,您可以创建该类的数组并使用比较器根据您需要的属性进行排序。

标签: java arrays string sorting comparator


【解决方案1】:

这是一个XY Question,因为这不是Java 中二维数组的正确用法。在 Java 中使用集合或 n 维数组时,该数据结构中的数据应始终属于同一类型(或至少在该类型的继承层次结构中)。

正如 Alexis C 在他/她的评论中提到的:Java 是一种面向对象的语言,因此您应该使用类的对象来包含数据。然后,您可以对该对象的特定字段的结构进行排序。

这是一个示例(我不确定数组的不同组件实际代表什么:

class MyClass {
     private string countryCode;
     private string names;
     private double score;

     public MyClass() {
         countryCode = null;
         names = null;
         score = 0d;
     }

     public string getCountryCode() { return this.countryCode; }
     public void setCountryCode(string code) { this.countryCode = code; }
     //repeat the above pattern for names & score
}    

然后您可以添加创建一个对象并将数据添加到其中:

 MyClass data = new MyClass();
 data.setCountryCode("GER");
 data.setNames("Nathalie WEINZIERL Maylin & Daniel Peter LIEBERS Nelli & Alexander");
 data.setScore(17.0);

这些数据可以添加到一个集合中,例如一个 ArrayList 并且可以排序。

List<MyClass> myDataCollection = new ArrayList<>();
myDataCollection.add(data);
//repeat for each object to populate the list

//sort the collection
Collections.sort(myDataCollection, Comparator.comparingDouble(s -> s.getScore()).reversed());

请记住,此示例适用于 Java 8。这允许我们使用 lambda 表达式而不是创建显式比较器。

【讨论】:

    【解决方案2】:

    使用 Java 8,您只需 create a Comparator 使用相应的列作为比较键,然后反转该比较器。这将对数组进行就地排序。

    Arrays.sort(infoArray, 
                Comparator.comparing((String[] entry) -> Double.parseDouble(entry[2]))
                          .reversed());
    

    或者对于旧版本的 Java,创建您自己的 Comparator 实现 compare

    Arrays.sort(infoArray, new Comparator<String[]>() {
        public int compare(String[] o1, String[] o2) {
            return Double.compare(Double.parseDouble(o2[2]), 
                                  Double.parseDouble(o1[2]));
        }
    });
    

    但是,如 cmets 中所述,可能值得为这些信息项创建 class 并让该类实现 Comparable

    class Info implements Comparable<Info> {
        String nation;
        String names;
        double score;
    
        // more stuff ...
    
        public int compareTo(Info other) {
            return Double.compare(this.score, other.score);
        }
    }
    

    然后这样排序:

    Arrays.sort(infoArray, Comparator.reverseOrder());
    

    【讨论】:

      【解决方案3】:

      您可以创建一个类并可以设置所有字段。在您的情况下,将有 3 个字段,您可以实现 Comparable 并且在 compareTo 方法中您可以编写自己的逻辑,这将取决于数值和 den 您可以使用 Collections 实用程序对其进行排序。

      如果您不想实现 Comparable 接口,您可以编写自己的 Comparator 类并将其传递给 Collections 实用方法,该方法将根据您的逻辑进行排序。

      如果您有重复,请避免使用集合。

      【讨论】:

        【解决方案4】:

        我想我会制作一个只包含分数的新列表。然后对这个分数列表进行排序。然后将分数替换为相关数组(包含国家、名称、分数)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-25
          • 2011-07-01
          • 2013-05-26
          • 2021-05-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多