sorting 2D array of String in java

Use Arrays.sort(arr, comparator) with a custom 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));

Output:

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


Beware:

you will be sorting the array you passed in, Arrays.sort() will not return a new array (in fact it returns void). If you want a sorted copy, do this:

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

And perform the sorting on theCopy, not theArray.


You must use the Arrays.sort() method. This method takes a Comparator as argument. The sort method delegates to the comparator to determine if one element of the array must be considered bigger, smaller or equal to another element. Since every element of the outer array is an array, the comparator will have to compare arrays (of Strings).

The arrays must be compared based on the value of their second element. This second element is a String which in fact represents a double number. So you'll have to transorm the strings into numbers, else the order will be lexicographical (20 come before 3) rather than numerical.

The comparator could thus look like this :

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

If you want to move away from arrays, here's a variation that uses List<Record> and a RecordComparator that implements Comparator<Record>.

Console:

joyce 35.0
zach 34.0
james 30.0
frank 23.0

Code:

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

/** @see http://stackoverflow.com/questions/5064027 */
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;
    }
}