Java Arrays.Sort 2D Array

java Arrays.sort 2d array

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

Understanding Java Sorting a 2D-Array using Arrays.sort()

The (a, b) -> Integer.compare(a[1], b[1]) is a lambda expression and in this case is an implementation of Comparator#compare(T,T). That method determines whether the first argument is less than, equal to, or greater than the second argument by returning a negative integer, zero, or a positive integer, respectively. The Integer.compare(int,int) method works the same way, just only with int arguments.

The sorting algorithm used by Arrays#sort(...) iterates over the array and compares its elements using the Comparator. The algorithm will consult the Comparator as many times as needed, using the results of the comparisons to determine which elements need to be moved, until the array is sorted.

A 2D array is essentially just an array of arrays. So what's happening is the "outer" array is being sorted based on the values at index 1 of the "inner" arrays.


If you're still unsure about the lambda expression it's equivalent to the following:

Arrays.sort(points, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
int a1 = a[1];
int b1 = b[1];

// Integer.compare(a1, b1)
if (a1 < b1) {
return -1; // negative = less than
} else if (a1 == b1) {
return 0; // zero = equal to
} else {
return 1; // positive = greater than
}
}
});

Assuming points is an int[][].

Sort a 2d array by the first column and then by the second one

Essentially what you want to do is to compare the inner arrays lexicographically (like how words are ordered in a dictionary). Arrays.compare does exactly that.

Arrays.sort(arrs, Arrays::compare);

Sort 2D array by average value of each line

The part of your code that calculates the average:

    float[] arrayAverage = new float[array1stDsize];
float average = 0;
for (int i = 0; i < array.length; i = i + 1) {
for (int j = 0; j < array[i].length; j = j + 1) {
average = average + array[i][j];
}
average = (float) (Math.round((average / array[i].length) * 100.0) / 100.0);
System.out.println(i + ". array average value: " + average);
arrayAverage[i] = average;
}

is slightly wrong, you need to set the average variable to zero before calculating the average of the next rows:

  ...
arrayAverage[i] = average;
average = 0;

With the Java Streams one can get the matrix sorted by average of rows pretty elegantly, namely:

Arrays.sort(array, comparingDouble(row -> IntStream.of(row)
.average()
.getAsDouble()));

To sort the array one uses the method Arrays.sort, and then for each row one gets its average as a double value IntStream.of(row).average().getAsDouble(), and used as the sorting parameter comparingDouble(....).

A running example:

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
import static java.util.Comparator.comparingDouble;

public class Test {
public static void main(String[] args) {
int array[][] = {{10, 20, 30},{40, 50, 60}, {1,2,3} };
Arrays.sort(array, comparingDouble(row -> IntStream.of(row).average().getAsDouble()));
Arrays.stream(array).map(Arrays::toString).forEach(System.out::println);
}
}

The output:

[1, 2, 3]
[10, 20, 30]
[40, 50, 60]

For the reverse order use instead:

Arrays.sort(array, comparing(row -> IntStream.of(row).average().getAsDouble(), reverseOrder()));

The output:

[40, 50, 60]
[10, 20, 30]
[1, 2, 3]

EDIT: WITH NO STREAMS

Without using streams what you can do is the following:

1 - Get the array with the averages of the matrix rows:

float[] arrayAverage = average(matrix);

You already know how to calculate the average, therefore you just need to extract a method out of the code that you have created, namely:

private static float[]average(int[][] array) {
float[] arrayAverage = new float[array.length];
float sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
sum += array[i][j];
}
arrayAverage[i] = (float) (Math.round((sum / array[i].length) * 100.0) / 100.0);
sum = 0;
}
return arrayAverage;
}

2 - Create an array that will represent the rows and initialized as the following:

int [] row_position = new int [arrayAverage.length];
for(int i = 0; i < row_position.length; i++)
row_position[i] = i;

3 - Sort the arrayAverage using the easiest sort, the bubble sort. While sorting that array update accordingly the positions stored on the row_position:

for(int i=0; i < arrayAverage.length; i++){
for(int j=1; j < (arrayAverage.length-i); j++){
if(arrayAverage[j-1] > arrayAverage[j]){
float temp = arrayAverage[j-1];
arrayAverage[j-1] = arrayAverage[j];
arrayAverage[j] = temp;
int temp_pos = row_position[j-1];
row_position[j-1] = row_position[j];
row_position[j] = temp_pos;
}
}
}

4 - Now that you have the row_positions array that tells you how the sorted rows should be rearranged, you just need to swap the rows accordingly:

    int[][] tmp_matrix = new int [matrix.lenght][];
for (int i = 0; i < tmp_matrix.length; i++) {
tmp_matrix[i] = matrix[row_position[i]];
}
matrix = new_matrix;

Bear in mind, however, that for simplicity-sake I have assumed a quadratic matrix of NxN, and the above solution can be improved performance-wise.

Sort a two dimensional array based on one column

Sort a two dimensional array based on one column

The first column is a date of format "yyyy.MM.dd HH:mm" and the second column is a String.

Since you say 2-D array, I assume "date of format ..." means a String. Here's code for sorting a 2-D array of String[][]:

import java.util.Arrays;
import java.util.Comparator;

public class Asdf {

public static void main(final String[] args) {
final String[][] data = new String[][] {
new String[] { "2009.07.25 20:24", "Message A" },
new String[] { "2009.07.25 20:17", "Message G" },
new String[] { "2009.07.25 20:25", "Message B" },
new String[] { "2009.07.25 20:30", "Message D" },
new String[] { "2009.07.25 20:01", "Message F" },
new String[] { "2009.07.25 21:08", "Message E" },
new String[] { "2009.07.25 19:54", "Message R" } };

Arrays.sort(data, new Comparator<String[]>() {
@Override
public int compare(final String[] entry1, final String[] entry2) {
final String time1 = entry1[0];
final String time2 = entry2[0];
return time1.compareTo(time2);
}
});

for (final String[] s : data) {
System.out.println(s[0] + " " + s[1]);
}
}

}

Output:

2009.07.25 19:54 Message R
2009.07.25 20:01 Message F
2009.07.25 20:17 Message G
2009.07.25 20:24 Message A
2009.07.25 20:25 Message B
2009.07.25 20:30 Message D
2009.07.25 21:08 Message E

Sort 2D String Array with respect to a column in Java

Use stream and Comparator Then you could sort that array how ever you want :

String[][] array1 = {{"54", "jim", "delhi"},
{"67", "dwight", "bangalore"},
{"39", "pam", "pune"}};

List<String[]> collect1 = Arrays.stream(array1).sorted(Comparator.comparing(a -> a[1])).collect(Collectors.toList());
String[][] sortedArray = new String[array1.length][3];
for (int i = 0; i < collect1.size(); i++) {
sortedArray[i] = collect1.get(i);
}
System.out.println(Arrays.deepToString(sortedArray));

How to sort 2D array in Java based on 1D array values

If you must do it in this manner then sorting the 2D array is no harder than sorting any other array. You have to remember that a 2D array is just an array of arrays. i.e just treat the inner array the way you would treat any other object in an array.

    static void sort(String[] students, int[][] grades, double[] finalGrade) {
double tempFinalGrade;
String tempStudent; //I think using well descriptive vars is better
int [] tempGrade;

//Bubble Sort
for (int i=0; i<students.length-1; i++) {
for (int j=0; j<finalGrade.length-i-1; j++) {
if (finalGrade[j] < finalGrade[j+1]) {
tempFinalGrade = finalGrade[j];
tempStudent = students[j];
tempGrade = grades[j];//addition

finalGrade[j] = finalGrade[j+1];
students[j] = students[j+1];
grades[j] = grades[j+1]; //addition

finalGrade[j+1] = tempFinalGrade;
students[j+1] = tempStudent;
grades[j+1] = tempGrade; //addition
}
}
}
}

I will say that I think this is not a good way at all to solve this problem. abstracting this in a class would be much better.

Sort 2D String array in java

You can use the Comparator function, but you have to comprehend how a 2D array is represented in the memory.

String[][] multi = new String [][]{
{"Josef", "cool"},
{"Josef", "bat"},
{"zeta", "doen"}
};

This means that multi is an array of array. The first index of multi is an array with contents "Josef" and "cool". The second "Josef" and "bat". And so on.

More visually:

multi ----> [ ][ ][ ]
| | |
| | \->["zeta", "doen"]
| |
| \-> ["Josef"]["bat"]
|
\-> ["Josef"]["cool"]

When using the Array.sort(), the comparator receives a 1D array as arguments. So when the arguments are String[] first, String[] second then in memory, you have (when the Array.sort() function is doing the first step)

first --> ["Josef"]["cool"]
second--> ["Josef"]["bat"]

So, in order to sort correctly, you have to check the first element. If it matches, then check the second element. Hence I've adapted your comparator class;

Arrays.sort(multi, new Comparator<String[]>(){
@Override
public int compare(String[] first, String[] second){
// compare the first element
int comparedTo = first[0].compareTo(second[0]);
// if the first element is same (result is 0), compare the second element
if (comparedTo == 0) return first[1].compareTo(second[1]);
else return comparedTo;
}
});

This should do the job.



Related Topics



Leave a reply



Submit