Java中对字符串的二维数组进行排序

7

我知道这个问题可能已经被问过了,但我找不到一个合适的答案。假设我有这个数组:

String[][] theArray = {
        {"james", "30.0"},
        {"joyce", "35.0"},
        {"frank", "3.0"},
        {"zach", "34.0"}};

有没有办法按每个子元素的第二个元素降序排序这个数组。所以我会得到像这样的东西。
theArray = {
        {"joyce", "35.0"},
        {"zach", "34.0"},
        {"james", "30.0"},
        {"frank", "3.0"}};
8个回答

10
使用自定义比较器,调用 Arrays.sort(arr, comparator)
Arrays.sort(theArray, new Comparator<String[]>(){

    @Override
    public int compare(final String[] first, final String[] second){
        // here you should usually check that first and second
        // a) are not null and b) have at least two items
        // updated after comments: comparing Double, not Strings
        // makes more sense, thanks Bart Kiers
        return Double.valueOf(second[1]).compareTo(
            Double.valueOf(first[1])
        );
    }
});
System.out.println(Arrays.deepToString(theArray));

输出:

[[joyce,35.0],[zach,34.0],[james,30.0],[frank,23.0]]


注意:

你将对传入的数组进行排序,Arrays.sort() 不会返回一个新的数组(实际上它返回 void)。如果你想要一个排序后的副本,请这样做:

String[][] theCopy = Arrays.copyOf(theArray, theArray.length);

排序应该在theCopy上进行,而不是在theArray上进行。


@Bart现在已将其添加到我的答案中。 - Sean Patrick Floyd
它适用于位数相同的数字,对于我有从0.0到9.0的数字,它会这样排序:0.0、1.0、10.0、11.0、15.0、2.0、23.0、3.0、32.0。 - Julio Diaz
@Julio,我一段时间前已经修改了我的答案。你试过比较Double值的当前版本了吗? - Sean Patrick Floyd

5
你必须使用Arrays.sort()方法。该方法接受一个Comparator作为参数。sort方法委托给比较器来确定数组的一个元素是否应被视为比另一个元素大、小或相等。由于外部数组的每个元素都是一个数组,因此比较器将必须比较字符串数组。
这些数组必须根据它们的第二个元素的值进行比较。第二个元素是一个表示双精度数字的字符串。因此,你需要将字符串转换成数字,否则排序顺序将是字典序的(20在3之前),而不是数值上的顺序。
因此,比较器可能看起来像这样:
public class StrinArrayComparator implements Comparator<String[]> {
    @Override
    public int compare(String[] array1, String[] array2) {
        // get the second element of each array, andtransform it into a Double
        Double d1 = Double.valueOf(array1.[1]);
        Double d2 = Double.valueOf(array2.[1]);
        // since you want a descending order, you need to negate the 
        // comparison of the double
        return -d1.compareTo(d2);
        // or : return d2.compareTo(d1);
    }
}

3

如果你想摆脱数组,这里有一种使用 List<Record> 和一个实现了 Comparator<Record> 接口的 RecordComparator 的变体。

控制台:

joyce 35.0
zach 34.0
james 30.0
frank 23.0

代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/** @see https://dev59.com/P1TTa4cB1Zd3GeqPtIVp */
public class ComparatorTest {
    public static void main(String[] args) {
        List<Record> list = new ArrayList<Record>(Arrays.asList(
            new Record("james", "30.0"),
            new Record("joyce", "35.0"),
            new Record("frank", "23.0"),
            new Record("zach",  "34.0")));
        print(list, Sort.DESCENDING, Field.D);
    }

    private static void print(List<Record> list, Sort s, Field f) {
        RecordComparator rc = new RecordComparator(s, f);
        Collections.sort(list, rc);
        for (Record r : list) {
            System.out.println(r);
        }
    }
}

class Record {

    private String s;
    private Double d;

    public Record(String name, String number) {
        this.s = name;
        this.d = Double.valueOf(number);
    }

    @Override
    public String toString() {
        return s + " " + d;
    }

    public int compareTo(Field field, Record record) {
        switch (field) {
            case S: return this.s.compareTo(record.s);
            case D: return this.d.compareTo(record.d);
            default: throw new IllegalArgumentException(
                "Unable to sort Records by " + field.getType());
        }
    }
}

enum Sort { ASCENDING, DESCENDING; }

enum Field {

    S(String.class), D(Double.class);

    private Class type;

    Field(Class<? extends Comparable> type) {
        this.type = type;
    }

    public Class getType() {
        return type;
    }
}

class RecordComparator implements Comparator<Record> {

    private Field field;
    private Sort sort;

    public RecordComparator(Sort sort, Field field) {
        this.sort = sort;
        this.field = field;
    }

    @Override
    public final int compare(Record a, Record b) {
        int result = a.compareTo(field, b);
        if (sort == Sort.ASCENDING) return result;
        else return -result;
    }
}

2
您似乎生活在物体否定之中。那些内部数组看起来很像有关个人的信息(包括姓名和某些值,可能是得分)。
您应该编写一个自定义类来保存这些信息:
public class Person {
  private final String name;
  private final double score;

  public Person(final String name, final double score) {
    this.name=name;
    this.score=score;
  }

  public String getName() {
    return name;
  }

  public double getScore() {
    return score;
  }
}

然后,当您想要对它们进行排序时,只需实现一个Comparator<Person>指定您想要它们排序的方式:
public PersonScoreComparator implements Comparator<Person> {
  public int compare(Person p1, Person p2) {
    return Double.compare(p1.getScore(), p2.getScore());
  }
}

或者,您可以让“Person”类本身通过添加以下方法来实现Comparable<Person>
public int compareTo(Person other) {
  return Double.compare(getScore(), other.getScore());
}

是的,我本来想自己写的,但我选择回答字面上的问题。最佳实践加一。 - Sean Patrick Floyd

0

公共静态无返回值主函数(String[] args) {

String Name[][]={{"prakash","kumar"},{"raj","kappor"},{"vinod","bhart"}};

String str[]=new String[2];


for(int j=0; j<Name.length;j++)
 {
     for (int i=0 ; i<2; i++)
     {
         str[i]=Name[j][i];
     }
 for(int i=0;i<str.length;i++)
 {
     for(int k=i+1;k<str.length;k++)
     {
         if(str[i].compareTo(str[k])>0)
         {
             String temp= str[i];
             str[i]=str[k];
             str[k]=temp;
         }

         }
     System.out.print(str[i]+ " ");
  }
 System.out.println();
 }



 }
}

0
-使用Arrays.toList()从此数组创建列表 -使用java.lang.comparator设计比较器,并编写逻辑以对每个偶数元素进行排序

1
它是 Arrays.asList(),而不是 Arrays.toList(),并且你不需要它,因为还有 Arrays.sort() - Sean Patrick Floyd

0

java.util.Arrays中有几种排序方法。其中两种采用自定义的Comparator。只需提供一个比较内部数组第二个元素的比较器即可。


0
/**
     *
     * @param array - 2D array required to be arranged by certain column
     * @param columnIndex - starts from 0; this will be the main comparator
     * @param hasHeaders - true/false; true - ignore the first row. False -
     * first row it's also compared and arranged
     * @return - the new arranged array
     */
    private String[][] arrangeArray(String[][] array, int columnIndex, boolean hasHeaders) {
        int headersExists = 0;
        if (hasHeaders) {
            headersExists = 1;
        }
        for (int i = headersExists; i < array.length; i++) {
            for (int j = headersExists; j < array.length; j++) {
            if (array[i][columnIndex].compareTo(array[j][columnIndex]) < 0){
                String[] temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }
    }
    return array;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接