21 responses to “Sorting a 2-Dimensional Array in Java”

  1. faith

    hmmmm…seriously it help me a lot…thanks

  2. Lars

    Dear Nitin,

    This post suddenly became a big post at dzone, hence i stumbled upon it. The problem you describe is indeed interesting, but your solution is as a matter of fact just a poor one. There are 2 major flaws: On one hand you copy the whole array, something you should actually avoid in a real life scenario, if we are talking about larger arrays, on the other hand your solution is not generic at all. It is just custom made for your “Array of Array of 4 Strings”-problem.

    Java Developer should know at least the core utils the JDK API provides. Your problem could be solved with actually 2 lines using tools from java.util:

    package example.sort2d;

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

    public class Sorter {

    public static <T extends Comparable> void sort(final T [][] toSort,final int onColumn) {
    List list = Arrays.asList(toSort);
    Collections.sort(list, new Comparator(){
    public int compare(T[] a, T[] b) {
    return a[onColumn].compareTo(b[onColumn]);
    }
    });
    }
    }

    and as a demonstration

    package example.sort2d;

    import org.junit.Assert;
    import org.junit.Test;

    public class ExampleTest {

    private final String[][] array = new String[][]
    {
    {“foo”,”bar”},
    {“a”,”b”},
    {“me”,”you”},
    {“by”,”now”}
    };

    @Test
    public void testSortOnFirstColumn(){
    Sorter.sort(array,0);

    assertInnerArray(array,0,”a”,”b”);
    assertInnerArray(array,1,”by”,”now”);
    assertInnerArray(array,2,”foo”,”bar”);
    assertInnerArray(array,3,”me”,”you”);
    }

    @Test
    public void testSortOnSecondColumn(){
    Sorter.sort(array,1);

    assertInnerArray(array,0,”a”,”b”);
    assertInnerArray(array,1,”foo”,”bar”);
    assertInnerArray(array,2,”by”,”now”);
    assertInnerArray(array,3,”me”,”you”);
    }

    private void assertInnerArray(T [][] onArray, int index, T … values){
    Assert.assertArrayEquals(onArray[index],values);
    }
    }

    Sincerely,
    Lars

    1. geek

      Lars,

      Did you compile the code you posted? The signature of compare is:

      int compare(Object o1, Object o2);

      Do some groundwork before posting!!! Thanks Nitin, it helped me :)

  3. Lars

    @Nitin

    Hi Nitin,

    First of all sorry, my comment may have sounded more harsh than it was supposed to be. And you are right, somehow i stopped reading before your “note” (I must admit it was late here).

    @geek
    Sorry, i don’t understand your point. Please have a look at http://java.sun.com/javase/6/docs/api/java/util/Comparator.html#compare(T, T)

    Best regards,
    Lars

  4. Anonymous Genius

    @Nitin : Thanks for the post. It was quite helpful. However I’d advice you to stick to Java naming conventions even with small examples like this. :)

    @Lars : Thanks for the alternative. It was helpful too! :)

    @geek : It’s you who should “do some groundwork before posting!” :P

  5. Lars

    Ok, now i see what went wrong. Of course and as usual all generics related <T> are eaten up by the browser. Actually my fault not to write them correctly. The correct version copied from my compiling IDE looks like

    package example.sort2d;

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

    public class Sorter {

        public static < T extends Comparable < T > > void sort(final T [][] toSort,final int onColumn) {
            List< T [] > list = Arrays.asList(toSort);
            Collections.sort(list, new Comparator < T [] >(){
                public int compare(T[] a, T[] b) {
                    return a[onColumn].compareTo(b[onColumn]);
                }
            });
        }
    }

    This blog might use some preview, that would be helpful.

  6. autofei

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

    public class Sorter {

    @SuppressWarnings(“unchecked”)
    public static void sort(final T[][] toSort,
    final int onColumn) {
    List list = Arrays.asList(toSort);
    Collections.sort(list, new Comparator() {
    public int compare(T[] a, T[] b) {
    return a[onColumn].compareTo(b[onColumn]);
    }

    @Override
    public int compare(Object o1, Object o2) {
    T[] a = (T[])o1;
    T[] b = (T[])o2;
    return compare(a,b);
    }
    });
    }

    public static void main(String[] args) {
    final String[][] array = new String[][] { { “foo”, “bar” },
    { “a”, “b” }, { “me”, “you” }, { “by”, “now” } };

    System.out.println(Arrays.deepToString(array));
    Sorter.sort(array, 0);
    System.out.println(Arrays.deepToString(array));
    }
    }

  7. autofei

    I just post a working version modified from Lars version. Hope it helpful.

  8. Bizunas

    Thanks, it helped me alot. No changes needed at all :)

  9. agil

    Hello Nitin,

    Your solution very useful for two Dimensional array with same length.
    My question is, can we sort two dimensional array based on some row and based on data length. for example we have an array {{”c”}, {”c”}, {”c”, “d”},{”c”, “a”},{”b”}}. how to get the sorted array like this {{”b”},{”c”},{”c”},{”c”,”a”},{”c”, “d”}}.

    Thx a lot Nitin.

  10. Line

    The solution is really helpful and I cannot imagine that I can make benefit of
    comparator to deal with array object by itself ..

    Thank you very much Nitin .

  11. amit

    Really helpful article

  12. Mark

    Quite often in multidimensional arrays, you may want to do a secondary sort on another column. For example, sort first on last name, then on first name if the last names are the same.

    Here are a couple extensions to Lars Feb 23, 2010 posting. I apologize in advance that some of the html might get eaten by the browser.

    The following code first is a copy of Lars’ posting, followed by code for sorting on two columns, then a third example on sorting by an arbitrary number of columns, using an array of column numbers as the input.

    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    public class TwoDcolumnComparator {
        public static < T extends Comparable> void sort(final T [][] toSort,final int onColumn) {
            List list = Arrays.asList(toSort);
            Collections.sort(
                list, new Comparator(){
                    public int compare(T[] a, T[] b) {
                        return a[onColumn].compareTo(b[onColumn]);
                    }
                }
            );
        }
        public static < T extends Comparable> void sort(final T [][] toSort,final int onColumn1, final int onColumn2) {
            List list = Arrays.asList(toSort);
            Collections.sort(
                list, new Comparator(){
                    public int compare(T[] a, T[] b) {
                        if (a[onColumn1].compareTo(b[onColumn1]) == 0) {
                            return a[onColumn2].compareTo(b[onColumn2]);
                        } else {
                            return a[onColumn1].compareTo(b[onColumn1]);
                        }
                    }
                }
            );
        }
        public static < T extends Comparable> void sort(final T [][] toSort,final int []onColumn) {
            List list = Arrays.asList(toSort);
            Collections.sort(
                list, new Comparator(){
                    public int compare(T[] a, T[] b) {
                        for (int i = 0;i < onColumn.length-1;i++){
                            if (a[onColumn[i]].compareTo(b[onColumn[i]]) != 0) {
                                return a[onColumn[i]].compareTo(b[onColumn[i]]);
                            }
                        }
                        return a[onColumn.length].compareTo(b[onColumn.length]);
                    }
                }
            );
        }
    }
  13. Thomas

    So why is it that

    Collections.sort(Arrays.asList(data))

    is faster than

    Arrays.sort(data)

    Can that really be?

  14. Kole Black

    Great article post.Much thanks again. Really Cool.

Leave a Reply

Open Source Projects

My Shared Items