Как создать массив приоритетных очередей? Далее, как назначить функцию сравнения каждому PQ в массиве

Я как-то наткнулся на требование создать массив PriorityQueues. Обходным путем может быть создание HashMap, но я предпочел массив.

Я объявил массив приоритетных очередей следующим образом.

PriorityQueue<long[]>[] arr = new PriorityQueue[10];

Я хотел, чтобы каждая приоритетная очередь в arr имела одну и ту же функцию сравнения, которая сортирует элементы в PriorityQueue<long[]> в порядке второго элемента внутри long[].

Я попытался заполнить массив arr с помощью.

Arrays.fill(arr, new PriorityQueue<>(new Comparator<>(){
            public int compare(int[] a, int[] b){
                return b[1] - a[1];
            }
        }));

Но это дает мне ошибку, может ли кто-нибудь помочь, что не так с этим подходом?

Код:

import java.util.*;
public class Main
{
    public static void main(String[] args) {
        PriorityQueue<long[]>[] arr = new PriorityQueue[10];
        Arrays.fill(arr, new PriorityQueue<>(new Comparator<>(){
            public int compare(int[] a, int[] b){
                return b[1] - a[1];
            }
        }));
    }
}

Ошибка:

Main.java:12: error: <anonymous Main$1> is not abstract and does not override abstract method compare(Object,Object) in Comparator
        Arrays.fill(arr, new PriorityQueue<>(new Comparator<>(){
                                                               ^
Main.java:13: error: method does not override or implement a method from a supertype
            public int compare(int[] a, int[] b){
                       ^
  (due to <>, every non-private method declared in this anonymous class must override or implement a method from a supertype)

Также есть ли лучший способ назначить объект каждому элементу массива во время объявления?

Является ли одно из сообщений об ошибке сообщением об ошибке компилятора «создание общего массива»? Те, кто обновляет Java, решили реализовать дженерики таким образом, что они несовместимы с массивами. Вы можете попробовать что-то вроде List<PriorityQueue<long[]>> arr = new ArrayList<>();

Old Dog Programmer 08.04.2023 19:29

Я добавил ошибку и полный код. Не могли бы вы объяснить, что именно вызывает эту ошибку?

Ayush Tiwari 09.04.2023 11:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы создать объект с компаратором, вы можете использовать этот подход:

PriorityQueue<Long[]> pq = new PriorityQueue<>(new Comparator<Long[]>() {
    public int compare(Long[] a, Long[] b) {
        return a[1].compareTo(b[1]);
    }
});

Но обратите внимание, что я использовал Long, а не long, и это позволяет мне также использовать compareTo вместо вычитания, чтобы гарантировать, что вы не столкнетесь с неожиданными результатами, выходящими за границы для возвращаемого значения Compareint.


В приведенном выше примере используется подход анонимного внутреннего класса, который вы хотели использовать в своем вопросе, но обратите внимание также на явный тип Comparator<Long[]>.

В качестве необязательного дополнительного шага это можно упростить, заменив внутренний класс лямбда-выражением:

PriorityQueue<Long[]> pq = new PriorityQueue<>((Long[] a, Long[] b) -> a[1].compareTo(b[1]));

Поэтому вы можете использовать любой из вышеперечисленных подходов в своем Arrays.fill.

Вот лямбда-подход:

PriorityQueue<long[]>[] arr = new PriorityQueue[10];
Arrays.fill(arr, new PriorityQueue<>((Long[] a, Long[] b) -> a[1].compareTo(b[1])));

Просто отметим - этот компаратор может быть только искусственным примером для этого вопроса, но он немного необычен. И мне было интересно, действительно ли вы хотели вместо этого сравнить a[0] с b[0].

И, очевидно, все очереди в этот момент пусты.


Обновлять

Полностью согласен с комментарием от @OldDogProgrammer. Смешивать дженерики и массивы таким образом не рекомендуется. «Предпочитайте списки массивам» — Джош Блох, «Эффективная Java».


Обновление 2

Вы спросили, могу ли я:

предоставить некоторые ссылки или некоторые материалы для чтения

Вот почему я упомянул Джоша Блоха и «Эффективную Java». Вы можете выполнить онлайн-поиск по запросу «предпочесть списки массивам josh bloch», чтобы увидеть различные статьи, в которых подробно обсуждается эта тема.

Вы спрашивали:

что вызывает ошибку здесь?

Вы не указали конкретный тип для new Comparator<>().

Вот почему я упомянул «обратите внимание также на явный тип Comparator<Long[]>» в своем ответе (см. Выше).

Объекты, которые вы хотите, чтобы компаратор сравнивал, являются Long[] массивами, но вы указали int[] в своей реализации:

compare(int[] a, int[] b)

Вы вообще не указали тип в своем конструкторе new Comparator<>(), поэтому по умолчанию он равен compare(Object,Object), что вы можете увидеть в сообщении об ошибке.

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

На самом деле это еще одна тема Джоша Блоха:

Отдавайте предпочтение универсальным типам.

На эту тему также есть отличные статьи в Интернете. Я ожидаю, что есть также несколько отличных ответов на переполнение стека по этому поводу и «Предпочитать списки массивам».

Вы также можете искать термины ковариантный и инвариантный в контексте дженериков и массивов Java в качестве другой темы исследования.

Не могли бы вы предоставить справку или материал для чтения о том, почему «Смешивание дженериков и массивов» не рекомендуется? Также я обновил вопрос, не могли бы вы объяснить, что здесь вызывает ошибку? Я пытаюсь заполнить массив новым объектом PriorityQueue, в котором я передал объект сравнения для каждого объекта PQ в массиве. Какую ошибку я делаю?

Ayush Tiwari 09.04.2023 11:59

ОК - я добавил несколько примечаний к своему ответу - надеюсь, они помогут. Это большие (и важные) темы, поэтому я попытался предоставить некоторые указатели для дальнейшего изучения.

andrewJames 09.04.2023 15:04

Спасибо за ваше время, это многое проясняет для меня.

Ayush Tiwari 15.04.2023 15:11

Другие вопросы по теме