How to find first 5 highest value in a two dimensional array?

拜拜、爱过 提交于 2021-01-28 11:30:47

问题


I have a two dimensional integer array. Row and Column information (locations of numbers) is important for me. So, I don't want to sort an array (matrix actually). How can I find the highest 5 value from this two dimensional array?

Here is my code:

for (int row = 0; row < matirx.length; row++) {
  for (int col = 0; col < matirx[row].length; col++) {
    if (matirx[row][col] > maxValue) {
      maxValue = matirx[row][col];
    }
  }
}

回答1:


First, I went for a streams solution that is very similar to other Answers. I didn't like the boxing and unboxing variations, but since IntStream doesn't have a fancy method that makes sorting with a Comparator straight out of the box, the IntStream has to be converted into a Stream in order to sort the values in reverse order. I didn't think it was important to return an int[] array, since we're only really interested in the values.

public static Integer[] streamIt(int[][] matrix, int n){
  Integer[] result = 
    Arrays.stream(matrix)                                         // stream the arrays
          // This is the same as using .flatMaptoInt(..) and then .boxed()
          .flatMap(a -> Arrays.stream(a)                          // stream the array in arrays
                              .mapToObj(i -> Integer.valueOf(i))) // turn the ints into Integers
          .sorted(Comparator.reverseOrder())                      // sort by higest values
          .limit(n)                                               // only pick n
          .toArray(i -> new Integer[i]);                          // put then in Integer array
  return result;
}

If you want them in an int[] array instead, look at the Answer by shadow.sabre that uses mapToInt() do to that.


While the streams solution is very neat and clean looking, I felt that the problem was really just to get the set of highest values, so inserting them into a standard java sorted Set made sense to me. I start off by inserting the values into the set until there are 5 elements in there. Then I check to see if the new value is higher than the lowest value, and if so, I just remove the lowest value while inserting the new one. Finding the lowest value is easy when using TreeSet as it's a sorted set.

The trick is to also check that the new value isn't already in the set. If there's already 5, 4, 3, 2, 1 in the set, and the new value is 5, then I don't want to remove the lowest value 1, since adding the new value wouldn't actually add any new elements to the Set. Remember a Set cannot contain duplicate values:

public static Set<Integer> useSet(int[][] matrix, int n){
  TreeSet<Integer> max = new TreeSet<>(Comparator.<Integer>naturalOrder().reversed());
  for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
      // Keep adding values until there's n elements in the Set
      if (max.size() < n) { 
        max.add(matrix[i][j]);
      } else {
        // if the new value is higher than the lowest value
        //  ..and the new values isn't already there.
        if (max.last() < matrix[i][j] && !max.contains(matrix[i][j])) {
          max.pollLast();
          max.add(matrix[i][j]);
        }
      }
    }
  }
  return max;
}

Note that this solution obviously never contains the same values, but always the top distinct ones.


Looking at the set solution it was easy to add the additional functionality of keeping track of where in the matrix the values were found. I created a class, Element, to contain the value and its location. Every element in the matrix that's to be inserted into the TreeSet is created as an Element.

The Element needs to either implement Comparable or the TreeSet has to be initialized with a Comparator in order to sort the elements. This example of Element has both, and I just used the static Comparator in the implementation of compareTo(Element that) to make it a Comparable<Element>. Normally you'd implement the class with private fields using getters to fetch the values, but for this purpose is seemed a little verbose. Making the fields final also ensures the class is immutable so I have no scruples about it.

Since the comparison is done using both the value and the location, every element from the matrix will be distinct:

class Element implements Comparable<Element> {
  final int value;
  final int x;
  final int y;

  static Comparator<Element> comparator = 
    Comparator.comparing((Element e) -> e.value)
              .thenComparing((Element e) -> e.x)
              .thenComparing((Element e) -> e.y)
              .reversed();

  Element(int value, int x, int y) {
    this.value = value;
    this.x = x;
    this.y = y;
  }

  public int compareTo(Element that){
    return comparator.compare(this, that);
  }

  public String toString(){
    return value + " at [" + x + "][" + y + "]";
  }
}

If the Element didn't implement the Comparable interface, this would be the initialization of the TreeSet:

TreeSet<Element> maxElement = new TreeSet<>(Element.comparator);

But since Element does implement the Comparable interface, the set implementation can be initialized without it:

public static Set<Element> useSetElements(int[][] matrix, int n){
  TreeSet<Element> maxElement = new TreeSet<>();
  for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
      if (maxElement.size() < n) {
        maxElement.add(new Element(matrix[i][j],i,j));
      } else {
        if (maxElement.last().value < matrix[i][j]) {
          maxElement.pollLast();
          maxElement.add(new Element(matrix[i][j],i,j));
        }
      }
    }
  }
  return maxElement;
}

Note that because every element is distinct, there's no need to also check that the new value isn't already in the set.


Running the three solutions with given input:

int n = 5;
int[][] matrix = {{16, -20, 22, 19}, 
                  { 2,   5,  6,  8},
                  {17,  25, 16, 19},
                  { 7,  18,  4, 17}};

System.out.println("streamIt: \n "
                   + Arrays.toString(streamIt(matrix,n)));
System.out.println("useSet: \n "
                   + useSet(matrix,n));
System.out.println("useSetElements: \n "
                   + useSetElements(matrix,n));                  

..gives this:

streamIt:
 [25, 22, 19, 19, 18]
useSet:
 [25, 22, 19, 18, 17]
useSetElements:
 [25 at [2][1], 22 at [0][2], 19 at [2][3], 19 at [0][3], 18 at [3][1]]

But what about Performance..?

The three different implementations had me wondering about the performance, so I added a method to time the execution:

static void timeMethod(Runnable toRun){
  long start = System.nanoTime();
  try{
    toRun.run();
  } finally {
    long end = System.nanoTime();
    System.out.println("  Time: " + (end - start)/1.0e6 + " miliseconds");
  }
}

And ran the three solutions:

timeMethod(() -> System.out.println("streamIt: \n "
                                    + Arrays.toString(streamIt(matrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
                                    + useSet(matrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
                                    + useSetElements(matrix,n)));

..giving this result:

streamIt:
 [25, 22, 19, 19, 18]
  Time: 1.2759 miliseconds
useSet:
 [25, 22, 19, 18, 17]
  Time: 0.9343 miliseconds
useSetElements:
 [25 at [2][1], 22 at [0][2], 19 at [2][3], 19 at [0][3], 18 at [3][1]]
  Time: 1.16 miliseconds

It seems that the three solutions have roughly the same performance. The streams solution seems slightly slower. The Set solution looks promising, expect the solution using Element seems to take a toll. But to look at it more deeply I decided to run them on a much larger matrix, which I build using random integers:

Random random = new Random();
int[][] largerMatrix =
  IntStream.range(0,10000)                     // 10000 on the first dimension
           .mapToObj(i -> random.ints(0,128)   // values between 0 and 128 (not included)
                                .limit(10000)  // 10000 on the second dimension
                                .toArray())    // make the second 1D arrays
           .toArray(int[][]::new);             // put them into a 2D array

Running the test with a 10000 by 10000 matrix:

timeMethod(() -> System.out.println("streamIt: \n "
                                    + Arrays.toString(streamIt(largerMatrix,n))));
timeMethod(() -> System.out.println("useSet: \n "
                                    + useSet(largerMatrix,n)));
timeMethod(() -> System.out.println("useSetElements: \n "
                                    + useSetElements(largerMatrix,n)));

..gave this result:

streamIt:
 [127, 127, 127, 127, 127]
  Time: 90374.6995 miliseconds
useSet:
 [127, 126, 125, 124, 123]
  Time: 2465.2448 miliseconds
useSetElements:
 [127 at [0][310], 127 at [0][277], 127 at [0][260], 127 at [0][81], 127 at [0][61]]
  Time: 1839.7323 miliseconds

Here the streams solution seems incredibly slow! The Element solution is the winner of the two Set solutions. I expect it's due to the fact that Elements are only created when they're needed for inserting into the Set and it's doing a straight up int comparison, while the other Set solution is unboxing every time the values are compared. I didn't further test my hypothesis though.


My curiosity of the other solutions in this thread got me testing out those as well. The solutions tested were:

  • Answer by Arvind Kumar Avinash
  • Answer by Anurag Jain
  • Answer by Michael Chatiskatzi

Running the tests on both the small and the large array:

System.out.println("--- Testing performance ---");
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
                                    + Arrays.toString(ArvindKumarAvinash(matrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
                                    + AnuragJain(matrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
                                    + Arrays.toString(MichaelChatiskatzi(matrix,n))));
                                        
System.out.println();
System.out.println("--- Testing performance with largeMatrix---");
timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
                                    + Arrays.toString(ArvindKumarAvinash(largerMatrix,n))));
timeMethod(() -> System.out.println("AnuragJain: \n "
                                    + AnuragJain(largerMatrix,n)));
timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
                                    + Arrays.toString(MichaelChatiskatzi(largerMatrix,n))));

..gave these results:

--- Testing performance ---
ArvindKumarAvinash:
 [25, 22, 19, 19, 18]
  Time: 0.9076 miliseconds
AnuragJain:
 [25, 22, 19, 19, 18]
  Time: 6.2277 miliseconds
MichaelChatiskatzi:
 [18, 19, 19, 22, 25]
  Time: 1.2204 miliseconds

--- Testing performance with largeMatrix---
ArvindKumarAvinash:
 [127, 127, 127, 127, 127]
  Time: 3381.1387 miliseconds
AnuragJain:
 [127, 127, 127, 127, 127]
  Time: 120244.7063 miliseconds
MichaelChatiskatzi:
 [127, 127, 127, 127, 127]
  Time: 51.4259 miliseconds

It seems that solutions using streams are not very performant at all. Michael Chatiskatzi's solution is by far the better performant one.

All the code

If you want to run it yourself, here a complete class for copy'n'paste'n'run:

import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

public class GettingTheTopN {
    public static void main(String[] args) {
      int n = 5;
      int[][] matrix = {{16, -20, 22, 19}, 
                        { 2,   5,  6,  8},
                        {17,  25, 16, 19},
                        { 7,  18,  4, 17}};

      System.out.println("streamIt: \n "
                         + Arrays.toString(streamIt(matrix,n)));
      System.out.println("useSet: \n "
                         + useSet(matrix,n));
      System.out.println("useSetElements: \n "
                         + useSetElements(matrix,n));

      System.out.println();
      System.out.println("--- Testing performance ---");

      timeMethod(() -> System.out.println("streamIt: \n "
                                          + Arrays.toString(streamIt(matrix,n))));
      timeMethod(() -> System.out.println("useSet: \n "
                                          + useSet(matrix,n)));
      timeMethod(() -> System.out.println("useSetElements: \n "
                                          + useSetElements(matrix,n)));
      timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
                                          + Arrays.toString(ArvindKumarAvinash(matrix,n))));
      timeMethod(() -> System.out.println("AnuragJain: \n "
                                          + AnuragJain(matrix,n)));
      timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
                                          + Arrays.toString(MichaelChatiskatzi(matrix,n))));

      System.out.println();
      System.out.println("--- Testing performance with largeMatrix---");

      Random random = new Random();
      int[][] largerMatrix =
        IntStream.range(0,10000)                     // 10000 on the first dimension
                 .mapToObj(i -> random.ints(0,128)   // values between 0 and 128 (not included)
                                      .limit(10000)  // 10000 on the second dimension
                                      .toArray())    // make the second 1D arrays
                 .toArray(int[][]::new);             // put them into a 2D array

      timeMethod(() -> System.out.println("streamIt: \n "
                                          + Arrays.toString(streamIt(largerMatrix,n))));
      timeMethod(() -> System.out.println("useSet: \n "
                                          + useSet(largerMatrix,n)));
      timeMethod(() -> System.out.println("useSetElements: \n "
                                          + useSetElements(largerMatrix,n)));
      timeMethod(() -> System.out.println("ArvindKumarAvinash: \n "
                                          + Arrays.toString(ArvindKumarAvinash(largerMatrix,n))));
      timeMethod(() -> System.out.println("AnuragJain: \n "
                                          + AnuragJain(largerMatrix,n)));
      timeMethod(() -> System.out.println("MichaelChatiskatzi: \n "
                                          + Arrays.toString(MichaelChatiskatzi(largerMatrix,n))));
    }

    public static Integer[] streamIt(int[][] matrix, int n){
      Integer[] result = 
        Arrays.stream(matrix)                                         // stream the arrays
              // This is the same as using .flatMaptoInt(..) and then .boxed()
              .flatMap(a -> Arrays.stream(a)                          // stream the array in arrays
                                  .mapToObj(i -> Integer.valueOf(i))) // turn the ints into Integers
              .sorted(Comparator.reverseOrder())                      // sort by higest values
              .limit(n)                                               // only pick n
              .toArray(i -> new Integer[i]);                          // put then in Integer array
      return result;
    }

    public static Set<Integer> useSet(int[][] matrix, int n){
      TreeSet<Integer> max = new TreeSet<>(Comparator.<Integer>naturalOrder().reversed());
      for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
          // Keep adding values until there's n elements in the Set
          if (max.size() < n) { 
            max.add(matrix[i][j]);
          } else {
            // if the new value is higher than the lowest value
            //  ..and the new values isn't already there.
            if (max.last() < matrix[i][j] && !max.contains(matrix[i][j])) {
              max.pollLast();
              max.add(matrix[i][j]);
            }
          }
        }
      }
      return max;
    }

    public static Set<Element> useSetElements(int[][] matrix, int n){
      TreeSet<Element> maxElement = new TreeSet<>();
      for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
          if (maxElement.size() < n) {
            maxElement.add(new Element(matrix[i][j],i,j));
          } else {
            if (maxElement.last().value < matrix[i][j]) {
              maxElement.pollLast();
              maxElement.add(new Element(matrix[i][j],i,j));
            }
          }
        }
      }
      return maxElement;
    }

    // ----------------- Performance

    static void timeMethod(Runnable toRun){
      long start = System.nanoTime();
      try{
        toRun.run();
      } finally {
        long end = System.nanoTime();
        System.out.println("  Time: " + (end - start)/1.0e6 + " miliseconds");
      }
    }

    // [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65374950/12695027) by [Arvind Kumar Avinash](https://stackoverflow.com/users/10819573/arvind-kumar-avinash)
    static int[] ArvindKumarAvinash(int[][] matrix, int MAX_N) {
        // Find count as the total number of elements
        int count = 0, row, col;
        for (row = 0; row < matrix.length; row++) {
            count += matrix[row].length;
        }

        // Create flattened = new int[count] and fill it with all elements of matrix[][]
        int[] flattened = new int[count];
        int i = 0;
        for (row = 0; row < matrix.length; row++) {
            for (col = 0; col < matrix[row].length; col++) {
                flattened[i++] = matrix[row][col];
            }
        }

        // Create max = new int[MAX_N] to store maximum n numbers.
        // Also, create maxPos = new int[MAX_N] to store the position of the maximum numbers.
        int[] max = new int[MAX_N];
        int[] maxPos = new int[MAX_N];

        // Loop MAX_N times. In each iteration, assume flattened[0] is the largest number.
        for (i = 0; i < max.length; i++) {
            max[i] = flattened[0];

            for (int j = 1; j < flattened.length; j++) {
                // If flattened[j] >= max[i], check if the position, j has already been
                // processed. If not assign flattened[j] to max[i] and j to maxPos[i].
                if (flattened[j] >= max[i]) {
                    boolean posAlreadyProcessed = false;
                    for (int k = 0; k <= i; k++) {
                        if (maxPos[k] == j) {
                            posAlreadyProcessed = true;
                            break;
                        }
                    }
                    if (!posAlreadyProcessed) {
                        max[i] = flattened[j];
                        maxPos[i] = j;
                    }
                }
            }
        }

        return max;
        // System.out.println("Largest " + MAX_N + " values: " + Arrays.toString(max));
    }

    // [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65380541/12695027) by [Anurag Jain](https://stackoverflow.com/users/5825625/anurag-jain)
    static List<Integer> AnuragJain(int[][] matrix, int n) {
      List<Integer> allVal = new ArrayList<>();

     for (int i = 0; i < matrix.length; i++) {
         for (int j = 0; j < matrix[i].length; j++) {
             allVal.add(matrix[i][j]);
         }
     }
      allVal = allVal.stream()
                     .sorted(Comparator.reverseOrder())
                     .limit(n).collect(Collectors.toList());
      return allVal;
      // System.out.println(allVal);
    }

    // [Answer to "How to find first 5 highest value in a two dimensional array?"](https://stackoverflow.com/a/65379921/12695027) by [Michael Chatiskatzi](https://stackoverflow.com/users/11263320/michael-chatiskatzi)
    static int[] MichaelChatiskatzi(int[][] matrix, int n) {
        // int[] highestNumbers = new int[5];
        int[] highestNumbers = new int[n];
        Arrays.fill(highestNumbers, Integer.MIN_VALUE);
        for (int row = 0; row < matrix.length; row++) {
            for (int column = 0; column < matrix[row].length; column++) {
                int currentEntry = matrix[row][column];
                if (currentEntry > highestNumbers[0]) {
                    highestNumbers[0] = currentEntry;
                    Arrays.sort(highestNumbers);
                }
            }
        }
        return highestNumbers;
        // System.out.println(Arrays.toString(highestNumbers));
    }
}


// -------------------------------------------
// -------------------------------------------
class Element implements Comparable<Element> {
  final int value;
  final int x;
  final int y;

  static Comparator<Element> comparator = 
    Comparator.comparing((Element e) -> e.value)
              .thenComparing((Element e) -> e.x)
              .thenComparing((Element e) -> e.y)
              .reversed();

  Element(int value, int x, int y) {
    this.value = value;
    this.x = x;
    this.y = y;
  }

  public int compareTo(Element that){
    return comparator.compare(this, that);
  }

  public String toString(){
    return value + " at [" + x + "][" + y + "]";
  }
}



回答2:


  1. Let MAX_N = 5.
  2. Find count as the total number of elements in matrix[][].
  3. Create flattened = new int[count] and fill it with all elements of matrix[][].
  4. Create max = new int[MAX_N] to store maximum n numbers. Also, create maxPos = new int[MAX_N] to store the position of the maximum numbers.
  5. Loop MAX_N times and in each iteration, assume flattened[0] is the largest number.
  6. If flattened[j] >= max[i], check if the position, j has already been processed. If not assign flattened[j] to max[i] and j to maxPos[i].

Demo:

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        final int MAX_N = 5;
        int[][] matrix = {
                {16, -20, 11, 19},
                {2, 5, 6, 8},
                {17, 25, 16, 19},
                {7, 17, 4, 17}};

        // Find count as the total number of elements
        int count = 0, row, col;
        for (row = 0; row < matrix.length; row++) {
            count += matrix[row].length;
        }

        // Create flattened = new int[count] and
        // fill it with all elements of matrix[][]
        int[] flattened = new int[count];
        int i = 0;
        for (row = 0; row < matrix.length; row++) {
            for (col = 0; col < matrix[row].length; col++) {
                flattened[i++] = matrix[row][col];
            }
        }

        // Create max = new int[MAX_N] to store maximum 
        // n numbers. Also, create maxPos = new int[MAX_N]
        // to store the position of the maximum numbers.
        int[] max = new int[MAX_N];
        int[] maxPos = new int[MAX_N];

        // Loop MAX_N times. In each iteration,
        // assume flattened[0] is the largest number.
        for (i = 0; i < max.length; i++) {
            max[i] = flattened[0];

            for (int j = 1; j < flattened.length; j++) {
                // If flattened[j] >= max[i], check if the
                // position, j has already been processed.
                // If not assign flattened[j] to max[i]
                // and j to maxPos[i].
                if (flattened[j] >= max[i]) {
                    boolean posAlreadyProcessed = false;
                    for (int k = 0; k <= i; k++) {
                        if (maxPos[k] == j) {
                            posAlreadyProcessed = true;
                            break;
                        }
                    }
                    if (!posAlreadyProcessed) {
                        max[i] = flattened[j];
                        maxPos[i] = j;
                    }
                }
            }
        }
        System.out.println("Largest " + MAX_N +
                " values: " + Arrays.toString(max));
    }
}

Output:

Largest 5 values: [25, 19, 19, 17, 17]



回答3:


With Java8 streams it can be done with this (one) line of code. It will leave the original matrix untouched.

Arrays.stream(matrix) // create a stream of the matrix
      .flatMapToInt(Arrays::stream) //Reduce 2d matrix to 1d 
      .boxed() //Convert int to Integer so we can sort reversed order
      .sorted(Collections.reverseOrder()) //sort array in reversed order highest first
      .limit(5) //Limit stream to 5 entries, the five top results
      .forEach(System.out::println); //Print the result



回答4:


Without sorting array itself, you can make sorted the stream over this array. Or you can implement a kind of selection sort in descending order. These two code examples do the same thing - find the first 5 highest distinct values in 2D array, if they are present:


  1. int[][] arr = {
            {1, 4, 7, 7},
            {2, 5, 8, 3},
            {5, 5, 1, 2},
            {3, 6, 0, 9}};
    
    int[] max = Arrays.stream(arr)
            .flatMapToInt(Arrays::stream)
            .boxed().sorted(Comparator.reverseOrder())
            .mapToInt(Integer::intValue)
            .distinct()
            .limit(5)
            .toArray();
    
    System.out.println(Arrays.toString(max)); // [9, 8, 7, 6, 5]
    

  1. int[][] arr = {
            {1, 4, 7, 7},
            {2, 5, 8, 3},
            {5, 5, 1, 2},
            {3, 6, 0, 9}};
    
    int[] max = new int[5];
    
    for (int m = 0; m < max.length; m++) {
        int prev_max = m > 0 ? max[m - 1] : Integer.MAX_VALUE;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (arr[i][j] > max[m] && prev_max > arr[i][j]) {
                    max[m] = arr[i][j];
                }
            }
        }
    }
    
    System.out.println(Arrays.toString(max)); // [9, 8, 7, 6, 5]
    

See also: Selection sort of array




回答5:


Now that the question is open again, I will present my comment as an answer.

Instead of iterating over the same matrix multiple times I fill the int[] highestNumbers with Integer.MIN_VALUE, iterate over the matrix once, and replace the smallest entry of max each time the current integer is greater, by updating the first entry of highestNumbers and sort it.

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[][] matrix = {
                {10, -5, 15},
                {8, 20, 12},
                {27, -3, 14},
                {7, 17, 4}};
        int[] highestNumbers = new int[5];
        Arrays.fill(highestNumbers, Integer.MIN_VALUE);
        for (int row = 0; row < matrix.length; row++) {
            for (int column = 0; column < matrix[row].length; column++) {
                int currentEntry = matrix[row][column];
                if (currentEntry > highestNumbers[0]) {
                    highestNumbers[0] = currentEntry;
                    Arrays.sort(highestNumbers);
                }
            }
        }
        System.out.println(Arrays.toString(highestNumbers));
    }
}

Output:

[14, 15, 17, 20, 27]



回答6:


You can use below way this will give you below benefits:

  • Keeping very simple logic, As you want highest 5 values and you will not loose any index location/order for existing array,
  • Using this you will get better performance,
  • Clean Code.
public static void main(String[] args) {
    int[][] matrix = {
            {10, -5, 15},
            {8, 20, 12},
            {27, -3, 14},
            {7, 17, 4}};

    List<Integer> allVal = new ArrayList<>();

    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            allVal.add(matrix[i][j]);
        }
    }

    allVal = allVal.stream()
            .sorted(Comparator.reverseOrder())
            .limit(5)
            .collect(Collectors.toList());

    System.out.println(allVal);
}

Output:

[27, 20, 17, 15, 14]


来源:https://stackoverflow.com/questions/65374379/how-to-find-first-5-highest-value-in-a-two-dimensional-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!