0

I want to sort a 2D array in ascending order using Arrays.sort().

For example, I have this array:

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

After sorting, the output should be:

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

Wrote code like this, but it sorts by rows:

package domain;

import java.util.Arrays;

public class Exercise {
    private int[][] matrix = {
            {34, 2, 15, 12, 56},
            {3, 67, 6, 21, 9},
            {22, 5, 18, 65, 10},
            {52, 36, 112, 90, 0},
            {19, 48, 73, 16, 88}};

    // Method that displays the array
    public void DisplayArray() {
        for (int[] row : matrix) {
            System.out.println(Arrays.toString(row));
        }
    }

    public void Sorting() {
        for (int[] row : matrix) {
            Arrays.sort(row);
        }
    }
}
0

4 Answers 4

1

Using streams, it is possible to convert the 2D array into a stream of integers and then recollect it to 2D array:

public static int[][] sort2D(int[][] arr) {
    int rows = arr.length;
    int cols = arr[0].length;
    int[] row = {0};
    
    return Arrays.stream(arr)
                 .flatMapToInt(Arrays::stream)
                 .sorted()
                 .boxed()
                 .collect(Collectors.groupingBy(x -> row[0]++ / cols))
                 .values()
                 .stream()
                 .map(r -> r.stream().mapToInt(Integer::intValue).toArray())
                 .toArray(int[][]::new);
}

Test

int[][] arr = {
  {9, 7, 5, 4},
  {3, 12, 11, 8},
  {6, 1, 2, 10}
};
int[][] sorted = sort2D(arr);
Arrays.stream(sorted)
      .map(Arrays::toString)
      .forEach(System.out::println);

Output

[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]

Update
A simpler solution is possible using method Stream::collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner):

public static int[][] sort2D(int[][] arr) {
    int rows = arr.length;
    int cols = arr[0].length;
    AtomicInteger ix = new AtomicInteger(0); // int[] ix = {0}; can be used too
    
    return Arrays
        .stream(arr)
        .flatMapToInt(Arrays::stream)
        .sorted()
        .collect(
            () -> new int[rows][cols], // supplier creating the result array
            (a, x) -> a[ix.get() / cols][ix.getAndIncrement() % cols] = x, // populate with sorted data
            (arr1, arr2) -> {} // nothing to combine
        );
}
Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, the easiest way to do this is to flat the dimensions
0

The problem can be broken down into three parts.

  1. Put all the elements of each row of size n in a single vector
  2. Order that vector
  3. Break it up into vectors of size n

With your example input

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

and method:

int[][] sorted(int[][] in) {
    int[] all = new int[in.length * in.length]; // assumption: square matrix
    int i = 0;
    for (int[] row : in) {
        for (int el : row) {
            all[i] = el;
            i++;
        }
    }
    Arrays.sort(all); // sort all elements in single vector
    // put sorted elements in your "output" array
    int[][] out = new int[in.length][in.length];
    int row = 0;
    int col = 0;
    for (int el : all) {
        // note col,row and not row,col!
        out[col][row] = el;
        row++;
        if (row == in.length) {
            row = 0;
            col++;
        }
    }
    return out;
}

You have

int[][] sorted = sorted(arr);

Comments

0

You can try this. got my reference here java Arrays.sort 2d array

Arrays.sort(matrix, (a, b) -> a[0] - b[0]);

1 Comment

This just sorts the rows by their first elements, without even sorting each row.
0

You can first flatten this 2d array to a one dimension, then sort a flat array with Arrays.sort method, and then assemble back a 2d array of the same dimensions with elements from the sorted flat array:

// original array
int[][] arr = {
        {3, 8, 5},
        {1, 6, 7},
        {2, 4, 9}};
// flatten a 2d array
int[] flatArr = Arrays.stream(arr).flatMapToInt(Arrays::stream).toArray();

// sorting
Arrays.sort(flatArr);
// reassemble a 2d array of the same dimensions from a flat array
AtomicInteger flatIndex = new AtomicInteger(0);
// iterate over the rows and their elements of
// the original array and sequentially fill the
// new array with elements from the flat array
int[][] sorted = Arrays.stream(arr)
        .map(row -> Arrays.stream(row)
                .map(j -> flatArr[flatIndex.getAndAdd(1)])
                .toArray())
        .toArray(int[][]::new);
// output
Arrays.stream(sorted).map(Arrays::toString).forEach(System.out::println);
//[1,2,3]
//[4,5,6]
//[7,8,9]

See also:
How do you rotate an array 90 degrees without using a storage array?
Filling a jagged 2d array first by columns

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.