108

I am looking to sort the following array based on the values of [][0]

double[][] myArr = new double[mySize][2];

so for example, myArr contents is:

1      5
13     1.55
12     100.6
12.1   .85

I want it to get to:

1      5
12     100.6
12.1   .85
13     1.55

I am looking to do this without having to implement my own sort.

vikash chander
  • 49
  • 1
  • 10
Dax Durax
  • 1,607
  • 5
  • 23
  • 31

16 Answers16

160

Use Overloaded Arrays#Sort(T[] a, Comparator c) which takes Comparator as the second argument.

double[][] array= {
{1, 5},
{13, 1.55},
{12, 100.6},
{12.1, .85} };

java.util.Arrays.sort(array, new java.util.Comparator<double[]>() {
    public int compare(double[] a, double[] b) {
        return Double.compare(a[0], b[0]);
    }
});

JAVA-8: Instead of that big comparator, we can use lambda function as following-

Arrays.sort(array, Comparator.comparingDouble(o -> o[0]));
Ashutosh
  • 917
  • 10
  • 19
PermGenError
  • 45,977
  • 8
  • 87
  • 106
  • 5
    That subtraction probably won't work; you should use `Double.compare(b[0], a[0])` instead. – Louis Wasserman Mar 16 '13 at 17:41
  • 2
    How can you pass 2D array as the argument when sort expects a 1D array? This didn't work for me. – user2441441 Dec 20 '13 at 15:44
  • @LouisWasserman I'm assuming they were using something like `a[0] - b[0]` before you said that. Why wouldn't it work? It's actually [a common sorting idiom for numbers](http://stackoverflow.com/a/1063027/5743988). – 4castle Jun 13 '16 at 15:18
  • Because a) it only even sort of works for ints, b) if you try it on big enough ints you get overflow and it explodes on you. Never use that idiom when the values you're comparing might be negative. – Louis Wasserman Jun 13 '16 at 16:07
  • @LouisWasserman I suppose so. It works fine with negative numbers btw. – 4castle Jun 13 '16 at 17:17
  • 3
    Not if they're big enough, is the point. If your numbers are always nonnegative, it's okay, but if you compare `Integer.MAX_VALUE` to `-1` you'll get overflow. It's just better to do the right thing from the start. – Louis Wasserman Jun 13 '16 at 17:17
98

Welcome Java 8:

Arrays.sort(myArr, (a, b) -> Double.compare(a[0], b[0]));
Marsellus Wallace
  • 17,991
  • 25
  • 90
  • 154
46

The simplest way:

Arrays.sort(myArr, (a, b) -> a[0] - b[0]);
X.walt
  • 483
  • 4
  • 6
  • 8
    I believe this can give wrong results at times, because of underflow/overflow issues. – Ayush Jan 08 '21 at 05:56
11

Decreasing/increasing order for an integer array of 2 dimension you can use:

Arrays.sort(contests, (a, b) -> Integer.compare(b[0],a[0])); //decreasing order
    
Arrays.sort(contests, (a, b) -> Integer.compare(a[0],b[0]); //increasing order
Stevie G
  • 5,638
  • 1
  • 10
  • 16
8

You need to implement a Comparator<Double[]> like so:

public static void main(String[] args) throws IOException {
    final Double[][] doubles = new Double[][]{{5.0, 4.0}, {1.0, 1.0}, {4.0, 6.0}};
    final Comparator<Double[]> arrayComparator = new Comparator<Double[]>() {
        @Override
        public int compare(Double[] o1, Double[] o2) {
            return o1[0].compareTo(o2[0]);
        }
    };
    Arrays.sort(doubles, arrayComparator);
    for (final Double[] arr : doubles) {
        System.out.println(Arrays.toString(arr));
    }
}

Output:

[1.0, 1.0]
[4.0, 6.0]
[5.0, 4.0]
Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
8

Although this is an old thread, here are two examples for solving the problem in Java8.

sorting by the first column ([][0]):

double[][] myArr = new double[mySize][2];
// ...
java.util.Arrays.sort(myArr, java.util.Comparator.comparingDouble(a -> a[0]));

sorting by the first two columns ([][0], [][1]):

double[][] myArr = new double[mySize][2];
// ...
java.util.Arrays.sort(myArr, java.util.Comparator.<double[]>comparingDouble(a -> a[0]).thenComparingDouble(a -> a[1]));
John
  • 81
  • 1
  • 1
  • How can I reversed it in descending order? I used `java.util.Arrays.sort(myArr, java.util.Comparator.comparingDouble(a -> a[0])).reversed(); ` But IDE gives me an error "Array type expected; found: 'java.lang.Object'" – lbrobinho Jul 01 '21 at 21:46
5

Simplified Java 8

IntelliJ suggests to simplify the top answer to the:

Arrays.sort(queries, Comparator.comparingDouble(a -> a[0]));
kyxap
  • 516
  • 6
  • 20
4

It is really simple, there are just some syntax you have to keep in mind.

Arrays.sort(contests, (a, b) ->
Integer.compare(a[0],b[0]));//increasing order     ---1

Arrays.sort(contests, (b, a) ->
Integer.compare(b[0],a[0]));//increasing order     ---2

Arrays.sort(contests, (a, b) ->
Integer.compare(b[0],a[0]));//decreasing order     ---3

Arrays.sort(contests, (b, a) ->
Integer.compare(a[0],b[0]));//decreasing order     ---4

If you notice carefully, then it's the change in the order of 'a' and 'b' that affects the result. For line 1, the set is of (a,b) and Integer.compare(a[0],b[0]), so it is increasing order. Now if we change the order of a and b in any one of them, suppose the set of (a,b) and Integer.compare(b[0],a[0]) as in line 3, we get decreasing order.

Apostolos
  • 10,033
  • 5
  • 24
  • 39
3

To sort in descending order you can flip the two parameters

int[][] array= {
    {1, 5},
    {13, 1},
    {12, 100},
    {12, 85} 
};
Arrays.sort(array, (b, a) -> Integer.compare(a[0], b[0]));

Output:

13, 5
12, 100
12, 85
1, 5
Magho
  • 334
  • 2
  • 6
1

much simpler code:

import java.util.Arrays; int[][] array = new int[][];

Arrays.sort(array, ( a, b) -> a[1] - b[1]);

ChristianS
  • 51
  • 2
0
import java.util.*;

public class Arrays2
{
    public static void main(String[] args)
    {
        int small, row = 0, col = 0, z;
        int[][] array = new int[5][5];

        Random rand = new Random();
        for(int i = 0; i < array.length; i++)
        {
            for(int j = 0; j < array[i].length; j++)
            {
                array[i][j] = rand.nextInt(100);
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }

        System.out.println("\n");


        for(int k = 0; k < array.length; k++)
        {
            for(int p = 0; p < array[k].length; p++)
            {
                small = array[k][p];
                for(int i = k; i < array.length; i++)
                {
                    if(i == k)
                        z = p + 1;
                    else
                        z = 0;
                    for(;z < array[i].length; z++)
                    {
                        if(array[i][z] <= small)
                        {
                            small = array[i][z];
                            row = i;
                            col = z;
                        }
                    }
                }
            array[row][col] = array[k][p];
            array[k][p] = small;
            System.out.print(array[k][p] + " ");
            }
            System.out.println();
        }
    }
}

Good Luck

0

Java 8 is now very common nowadays.

Arrays.sort(myArr,(double[] a,double[] b)->{
                //here multiple lines of code can be placed
                return a[0]-b[0]; 
            });
ZhaoGang
  • 4,491
  • 1
  • 27
  • 39
0

You can use your own sort, it is very simple.

int[][] matrix = {
            {2, 1, 3},
            {5, 4, 6},
            {8, 7, 9}
        };

for (int k = 0; k < length; k++) {
        for (int i= 0; i < matrix[k].length; i++) {
            for (int j = 0; j < matrix[k].length; j++) {
                if (matrix[k][i] < matrix[k][j]) {
                    int temp = matrix[k][i];
                    matrix[k][i] = matrix[k][j];
                    matrix[k][j] = temp;
                }
            }
        }
    }

System.out.println(Arrays.deepToString(matrix));

OUTPUT

[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
0

There are multiple approaches to do this, Here I'm sharing follow two methods by which it can be achieved.

  • Using Comparator Arrays.sort : An built-in feature of Java.
  • Using Merge Sort

Using Comparator Arrays.sort : A built-in feature of Java.

import java.util.Arrays;

class Array2D {
    public static void printTwoDimensionArray(int [][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[0].length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println("");
        }
    }

    public static void main(String [] args) {
        int [][] arr = {
                            {1, 2},
                            {6, 8},
                            {4, 7},
                            {9, 11},
                            {7, 10},
                            {13, 16},
                            {5, 9},
                            {8, 9},
                            {10, 11}
                        };
        Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
        printTwoDimensionArray(arr);
    }
}

Using Merge Sort

import java.util.ArrayList;

class MergeSortComparator {
    
    public static void printSingleDimensionArray(int [] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println("");
    }

    public static void printDoublyDimensionArray(int [][] arr) {
       for (int i = 0; i < arr.length; i++) {
           for (int j = 0; j < arr[0].length; j++) {
               System.out.print(arr[i][j] + " ");
           }
           System.out.println("");
       }
    }

    public static void merge(int[][] arr, int start, int mid, int end, int index) {
        int i, j, k;
        int n1 = mid - start + 1;
        int n2 = end - mid;
        int columnLength = arr[0].length;
        int [][] leftSubArray = new int [n1][columnLength];
        int [][] rightSubArray = new int [n1][columnLength];
        
        // Copy elements to Temp LeftSubArray
        for (i = 0; i < n1; i++) {
            for (j = 0; j < columnLength; j++) {
                leftSubArray[i][j] = arr[start + i][j];
            }
        }

        // Copy elements to Temp RightSubArray
        for (i = 0; i < n2; i++) {
            for (j = 0; j < columnLength; j++) {
                rightSubArray[i][j] = arr[mid + 1 + i][j];
            }
        }

        i = j = k = 0;
        while(i < n1 && j < n2) {
            if (leftSubArray[i][index] <= rightSubArray[j][index]) {
                arr[start + k] = leftSubArray[i];
                i++;
            } else {
                arr[start + k] = rightSubArray[j];
                j++;
            }
            k++;
        }
        while(i < n1) {
            arr[start + k] = leftSubArray[i];
            i++;
            k++;
        }
        while(j < n2 && (start + k) < end) {
            arr[start + k] = rightSubArray[j];
            j++;
            k++;
        }
        
    }

    public static void mergeSort(int[][] arr, int start, int end, int index) {
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        mergeSort(arr, start, mid, index);
        mergeSort(arr, mid + 1, end, index);
        merge(arr, start, mid, end, index);
        return;
    }
    
    public static void main(String [] args) {
        int [][] arr = {
                            {1, 2},
                            {6, 8},
                            {4, 7},
                            {9, 11},
                            {7, 10},
                            {13, 16},
                            {5, 9},
                            {8, 9},
                            {10, 11}
                        };
        
        int m = arr.length;
        int n = arr[0].length;
        // Last argument as Index is set to 0,
        mergeSort(arr, 0, m-1, 0);
        printDoublyDimensionArray(arr);
    }
}
sujit
  • 63
  • 6
0

To sort 2-D array lexicographically.
First sort each ArrayList in the Array<ArrayList>.

ArrayList<ArrayList<Integer>> allSubset = new ArrayList<>();

for(ArrayList<Integer> row : allSubset) {
     Collections.sort(row);
}

Second sort the whole ArrayList<ArrayList> in lexicographically.

allSubset.sort((ArrayList<Integer> o1, ArrayList<Integer> o2) -> {
            if(o2.size() == 0) return 1;
            int min = Math.min(o1.size(), o2.size());
            int i;
            for(i = 0; i < min - 1; i++) {
                if(o1.get(i).equals(o2.get(i))) continue;
                return o1.get(i).compareTo(o2.get(i));
            }
            return o1.get(i).compareTo(o2.get(i));
        });

or

        Collections.sort(allSubset, (ArrayList < Integer > first, ArrayList < Integer > second) -> {
            for (int i = 0; i < first.size() && i < second.size(); i++) {
                if (first.get(i) < second.get(i))
                    return -1;
                if (first.get(i) > second.get(i))
                    return 1;
            }
            if (first.size() > second.size())
                return 1;
            return -1;
        });
-1

For a general solution you can use the Column Comparator. The code to use the class would be:

Arrays.sort(myArr, new ColumnComparator(0));
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Some people don't like answers that link to an external website. You may want to consider newer approaches, as new features have been added to the language. – camickr Apr 07 '20 at 20:35
  • From what version, this feather is available? – ZhaoGang Apr 11 '20 at 12:17
  • It is not part of the Java API. It is a stand alone class that can be used with any version. – camickr Apr 11 '20 at 15:14