(Java) лямбда-выражение приоритетной очереди

#java

#java

Вопрос:

Я сам изучаю Java8. Я не понимаю разницы между

 PriorityQueue<Node> heap = new PriorityQueue<Node>((n1, n2) -> matrix[n2.row][n2.col] - matrix[n1.row][n1.col]);
  

и

 PriorityQueue<Node> heap = new PriorityQueue<Node>((n1, n2) -> matrix[n1.row][n1.col] - matrix[n2.row][n2.col]);
  

Предположим, что ввод и вывод приведены ниже:

 matrix = [[1,5,9],[10,11,13],[12,13,15]];
k = 8
  

Я добавил несколько значений матрицы, используя приведенный ниже код:

 for(int i = 0; i < matrix.length; i  ) {
  if(i < k){
    heap.add(new Node(i, 0));
  }
}
  
 class Node{
    int row;
    int col;
    
    public Node(int row, int col) {
        this.row = row;
        this.col = col;
    }
}
  

В этом случае в кучу добавляются 3 разных значения матрицы.

  1. PriorityQueue<Node> heap = new PriorityQueue<Node>((n1, n2) -> matrix[n2.row][n2.col] - matrix[n1.row][n1.col])

12, 1, 10

  1. PriorityQueue<Node> heap = new PriorityQueue<Node>((n1, n2) -> matrix[n1.row][n1.col] - matrix[n2.row][n2.col])

1, 10, 12

2-й код показывает минимальную кучу. Кто-нибудь знает разницу между matrix[n2.row][n2.col] - matrix[n1.row][n1.col] и matrix[n1.row][n1.col] - matrix[n2.row][n2.col] ?

Комментарии:

1. У вас где-то опечатка. Первые два блока кода показывают разницу в порядке следования операндов (x-y против y-x), но в другом месте вы повторяете ту же версию.

Ответ №1:

В вашем случае лямбда-выражение представляет собой пользовательский компаратор, который сравнивает два своих аргумента для упорядочения, возвращает отрицательное целое число, ноль или положительное целое число, поскольку первый аргумент меньше, равен или больше второго. Поскольку вы можете настроить его, вы даже можете возвращать отрицательное число, когда первый аргумент численно больше второго аргумента. Предположим matrix[n1.row][n1.col] , что больше, чем matrix[n2.row][n2.col] , в вашем первом коде лямбда-выражение вернет положительное число, во втором коде оно вернет отрицательное число наоборот.

В PriorityQueue он всегда ставит одинаковые единицы перед большими, другими словами, он хранит элементы в порядке возрастания (для простоты предположим, что они упорядочены внутри). Но порядок определяется вашим пользовательским компаратором, если вы его предоставляете, когда вы добавляете узлы в PriorityQueue by heap.add(new Node(i, 0)); , он, наконец, переходит к этому методу:

     private void siftUpUsingComparator(int k, E x) {
        while (k > 0) {
            int parent = (k - 1) >>> 1;
            Object e = queue[parent];
            // this is where the custom comparator being used, x is the first argument, 
            // e is the second argument. When it return a positive integer or zero, 
            // x will be positioned after e since comparator says x is greater than e.            
            if (comparator.compare(x, (E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = x;
    }