Java 如何对对象的矩阵进行排序

Java 如何对对象的矩阵进行排序,java,Java,我正在开发一个应用程序,该应用程序使用ApachePOI读取Excel文件。我将单元格值放入字符串对象的矩阵中 [title 1][title 2][title 3] [mark] [smith] [34] [simon] [black] [24] 我被要求允许根据所选列对矩阵进行排序。 如何对字符串对象的矩阵进行排序 谢谢你如果你只有几列,你可以创建一些有意义的比较器,并按如下方式排序: public static void main(String[] args) {

我正在开发一个应用程序,该应用程序使用ApachePOI读取Excel文件。我将单元格值放入字符串对象的矩阵中

[title 1][title 2][title 3]
[mark]   [smith]  [34]
[simon]  [black]  [24]
我被要求允许根据所选列对矩阵进行排序。 如何对字符串对象的矩阵进行排序


谢谢你

如果你只有几列,你可以创建一些有意义的比较器,并按如下方式排序:

    public static void main(String[] args) {
    String[][] matrix = {{"mark","smith","34"},
                         {"simon","black","24"},
                         {"foo","bar","44"}
                        };        

    Comparator<String[]> firstNameComparator  = new Comparator<String[]>() {
        @Override
        public int compare(String[] row1, String[] row2) {
            return row1[0].compareTo(row2[0]);
        }
    };
    Comparator<String[]> lastNameComparator  = new Comparator<String[]>() {
        @Override
        public int compare(String[] row1, String[] row2) {
            return row1[1].compareTo(row2[1]);
        }
    };
    Comparator<String[]> ageComparator  = new Comparator<String[]>() {
        @Override
        public int compare(String[] row1, String[] row2) {
            return Integer.compare(Integer.parseInt(row1[2]), Integer.parseInt(row2[2]));
        }
    };
    Arrays.sort(matrix, firstNameComparator);// pass the desired comparator
    for(String[] row:matrix){
        System.out.println(Arrays.toString(row));
    }
}
使用java 8和streams,您可以更简洁地编写它:

String[][] sorted = Arrays.stream(matrix)
                          .sorted((s1,s2)->s1[1].compareTo(s2[1])) // pass the desired index
                          .toArray(String[][]::new);
for(String[] row: sorted){
    System.out.println(Arrays.toString(row));
}
编辑

因为您更喜欢流方法,所以我只修改了这个方法。但您也可以将其用于其他方法。您可以在比较之前检查相应列是否包含数字,并使用简单的if-else对数字或字符串进行比较

    int colIndex  = 2;
    String[][] sorted = Arrays.stream(matrix).sorted((s1,s2)-> {
                            if(s1[colIndex].matches("(\\d+(?:\\.\\d+)?)")){
                                return Double.compare(Double.parseDouble(s1[colIndex]), Double.parseDouble(s2[colIndex]));
                            }
                            else{
                                return s1[2].compareTo(s2[2]);
                            }}) 
                      .toArray(String[][]::new);

    for(String[] row: sorted){
        System.out.println(Arrays.toString(row));
    }

使用此
(\d+(?:\.\d+)
正则表达式来匹配整数和浮点数。

首先感谢您提出这个问题,将此解决方案可视化并实现在思想上是一个相当大的挑战。我希望以下解决方案是您想要的

我已经编写了一个方法,可以为您排序矩阵。该方法将
字符串
矩阵作为参数,并返回一个新的
字符串
矩阵,每个列按字母顺序排序。排序是独立于其他列进行的,因此每个列在没有外部上下文的情况下进行排序

不幸的是,它并不排除排序过程中的标题,所以如果你需要这样做,请让我知道,我会尽我所能实现这一点

public static boolean isNumeric(String str) {
    return str.matches("^[0-9]+$");
}

public static String[][] sortMatrix(String[][] matrix)
{
    int matrixLength = matrix[0].length;

    String[][] sortedMatrix = new String[matrixLength][];
    java.util.List<String[]> columns = new java.util.ArrayList<>();

    for (int i1 = 0; i1 < matrixLength; i1++)
    {
        String[] column = new String[matrixLength];
        for (int i2 = 0; i2 < matrixLength; i2++) {
            column[i2] = matrix[i2][i1];
        }
        columns.add(column);
    }

    // First sort the column before proceeding
    columns.forEach(column -> Arrays.sort(column, new Comparator<String>()
    {
        public int compare(String s1, String s2)
        {
            boolean i1 = isNumeric(s1);
            boolean i2 = isNumeric(s2);

            if (i1 && i2) {
                return Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
            }
            else if (!i1) {
                return 1;
            }
            else return -1;
        }
    }));

    for (int i1 = 0; i1 < columns.size(); i1++)
    {
        String[] row = new String[matrixLength];
        for (int i2 = 0; i2 < matrixLength; i2++) {
            row[i2] = columns.get(i2)[i1];
        }
        sortedMatrix[i1] = row;
    }
    return sortedMatrix;
}

public static void main(String[] args) throws IOException {

    String[][] matrix = new String[3][] ;
    matrix[0] = new String[] { "title 1", "title 2", "title 3" };
    matrix[1] = new String[] { "simon", "1", "10" };
    matrix[2] = new String[] { "mark", "35", "2" };

    matrix = sortMatrix(matrix);
    for (String[] row : matrix) {
        System.out.println(Arrays.toString(row));
    }
}
公共静态布尔值isNumeric(字符串str){
返回str.matches(“^[0-9]+$”;
}
公共静态字符串[][]sortMatrix(字符串[][]矩阵)
{
int matrixLength=矩阵[0]。长度;
字符串[][]sortedMatrix=新字符串[矩阵长度][];
java.util.List columns=new java.util.ArrayList();
对于(int i1=0;i1<矩阵长度;i1++)
{
字符串[]列=新字符串[矩阵长度];
对于(int i2=0;i2<矩阵长度;i2++){
列[i2]=矩阵[i2][i1];
}
列。添加(列);
}
//在继续之前,首先对列进行排序
columns.forEach(column->Arrays.sort(column,newcomparator())
{
公共整数比较(字符串s1、字符串s2)
{
布尔值i1=isNumeric(s1);
布尔值i2=isNumeric(s2);
如果(i1和i2){
返回Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
}
如果(!i1){
返回1;
}
否则返回-1;
}
}));
for(int i1=0;i1

编辑:实现了一个考虑数字的自定义比较器。

然后按什么标准排序?按列,即数字或字符串我要解决的第一个问题是设计:为什么要将所有内容都放在字符串矩阵中?为什么不创建一个表示该文件内容的Pojo类呢?那适合你吗?还有:excel是否总是由相同的列组成?需要更多信息:)因为这是我从其他开发者那里得到的软件。我最初的问题仍然有效,具体依据什么标准?你想按字母顺序排序还是类似的方式排序?我喜欢Java 8单线解决方案,工作起来很有魅力。非常感谢你的大力帮助。问题是,在由字符串组成的矩阵中,字符串实际上可以包含一个数字(1,45.48,ecc.),我也应该对“数字”进行排序。我很漂亮confused@MDP编辑了我的答案。希望能有帮助。真的谢谢你的大力帮助。问题是,在由字符串组成的矩阵中,字符串实际上可以包含一个数字(1,45.48,ecc.),我也应该对“数字”进行排序。我很困惑,我已经更新了我的答案,所以实现对数字很敏感。现在一切都应该开始了。如果代码执行中有任何问题,请告诉我。
public static boolean isNumeric(String str) {
    return str.matches("^[0-9]+$");
}

public static String[][] sortMatrix(String[][] matrix)
{
    int matrixLength = matrix[0].length;

    String[][] sortedMatrix = new String[matrixLength][];
    java.util.List<String[]> columns = new java.util.ArrayList<>();

    for (int i1 = 0; i1 < matrixLength; i1++)
    {
        String[] column = new String[matrixLength];
        for (int i2 = 0; i2 < matrixLength; i2++) {
            column[i2] = matrix[i2][i1];
        }
        columns.add(column);
    }

    // First sort the column before proceeding
    columns.forEach(column -> Arrays.sort(column, new Comparator<String>()
    {
        public int compare(String s1, String s2)
        {
            boolean i1 = isNumeric(s1);
            boolean i2 = isNumeric(s2);

            if (i1 && i2) {
                return Integer.valueOf(s1).compareTo(Integer.valueOf(s2));
            }
            else if (!i1) {
                return 1;
            }
            else return -1;
        }
    }));

    for (int i1 = 0; i1 < columns.size(); i1++)
    {
        String[] row = new String[matrixLength];
        for (int i2 = 0; i2 < matrixLength; i2++) {
            row[i2] = columns.get(i2)[i1];
        }
        sortedMatrix[i1] = row;
    }
    return sortedMatrix;
}

public static void main(String[] args) throws IOException {

    String[][] matrix = new String[3][] ;
    matrix[0] = new String[] { "title 1", "title 2", "title 3" };
    matrix[1] = new String[] { "simon", "1", "10" };
    matrix[2] = new String[] { "mark", "35", "2" };

    matrix = sortMatrix(matrix);
    for (String[] row : matrix) {
        System.out.println(Arrays.toString(row));
    }
}