Как преобразовать Object[] в int[] в java

После того, как я использую метод .toArray() в приоритетной очереди целых чисел, я получаю такой массив объектов:

Object[] objects = pq.toArray();

Однако мне нужно, чтобы массив был int[]. Я пробовал:

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

но он говорит:

Cannot cast from Object[] to int[]

Как я могу этого добиться?

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

Ответы 3

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

Все коллекции предоставляют альтернативную реализацию toArray с указанием типа элемента:

Integer[] objects = pq.toArray(Integer[]::new);

Обратите внимание, что для этого требуется Java v11 или выше.

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collection.html#toArray(java.util.function.IntFunction)

Обратите внимание, что в этом случае результирующий массив, очевидно, представляет собой целочисленные объекты-оболочки, не знаю, подходит ли это для ваших требований.

РЕДАКТИРОВАТЬ - быстрый тест:

PriorityQueue<Integer> q = new PriorityQueue<>();
q.add(42);
System.out.println(Arrays.toString(q.toArray(Integer[]::new)));

Метод toArray(T[]) в типе PriorityQueue<Integer> неприменим для аргументов (Integer[]::new)

user13404388 15.12.2020 14:31

Целевой тип этого выражения должен быть функциональным интерфейсом.

user13404388 15.12.2020 14:32

Несовместимый список параметров для конструктора массива. Ожидалось (int), но найдено ()

user13404388 15.12.2020 14:32

Это 3 сообщения об ошибках, которые я получаю, когда использую это выражение.

user13404388 15.12.2020 14:32

@PabloBiedma Пожалуйста, опубликуйте объявление своей очереди. Ваш пост подразумевает, что это было PriorityQueue<Integer>?

stridecolossus 15.12.2020 14:34

PriorityQueue<Integer> pq = new PriorityQueue<>();

user13404388 15.12.2020 14:35

Добавил тестовый код к моему ответу, выглядит точно так же, как ваш, странно. Вы используете Java v8+, да?

stridecolossus 15.12.2020 14:37

@stridecolossus Ваше текущее решение не может работать: есть две toArrays. Первый из интерфейса Collection требует предоставления целевого массива, скажем q.toArray(new Integer[q.size()]). Второй, из интерфейса BaseStream, требует фабричного метода для создания массива заданной длины, скажем, q.stream().toArray(Integer[]::new). Вы смешали оба в один, поэтому он не работает.

terrorrussia-keeps-killing 15.12.2020 14:42

@fluffy Ничего общего с потоками, это метод по умолчанию в базовом классе коллекции: docs.oracle.com/javase/7/docs/api/java/util/…. Также обратите внимание, что есть две реализации.

stridecolossus 15.12.2020 14:46

@stridecolossus Это часть того, о чем я говорю. Пожалуйста, перечитайте. Ваш код не может скомпилироваться из-за смешения идей из обоих toArrays. Вы запутались с этим: docs.oracle.com/javase/8/docs/api/java/util/stream/…

terrorrussia-keeps-killing 15.12.2020 14:48

@fluffy Попробуйте код, он компилируется и запускается, это именно то, что я сделал! Пример из JavaDoc делает именно это: String[] y = x.toArray(String[]::new). Также обратите внимание на делегаты реализации по умолчанию для другой реализации toArray.

stridecolossus 15.12.2020 14:52

@stridecolossus Вы понимаете, что x.toArray(new String[0]); (из примера) — это не то же самое, что x.toArray(String[]::new)? Опять же, javac отклоняет ваше решение, помеченное как «быстрый тест» с помощью error: no suitable method found for toArray(Integer[]::new).

terrorrussia-keeps-killing 15.12.2020 14:56

@fluffy @Pablo Biedma Какую версию Java вы используете? Реализация toArray, которую я использовал в приведенном выше фрагменте, — это @since 11. Если вы используете более старую версию, то, очевидно, этот метод не существует, поэтому возникает ошибка.

stridecolossus 15.12.2020 14:59

@stridecolossus Извините, не понял, что вы имеете в виду docs.oracle.com/en/java/javase/11/docs/api/java.base/java/ut‌​il/… начиная с Java 11 (Я все еще в мире Java 8, и новые методы, подобные этим, в очень старых интерфейсах проходят мимо меня). Теперь это имеет смысл.

terrorrussia-keeps-killing 15.12.2020 15:02

@fluffy Да, я только что понял, что разместил старую версию JavaDoc, чтобы еще больше запутать ситуацию, да! Измененный ответ соответственно.

stridecolossus 15.12.2020 15:03

@stridecolossus Еще раз извините за это. Я знаю о выпусках Java после 8, но обычно не обращаю особого внимания на изменения API, особенно те, которые затрагивают старые API, но уделяю больше внимания языковым изменениям. Так вот где моя "древность" из мира Java 8 сыграла роль неверного истолкования. Я был действительно сбит с толку старым справочником Javadoc 7, поэтому я подумал, что это опечатка, которая смешивает вещи. Хорошего дня и спасибо за пометку «Java 11+» к вашему ответу!

terrorrussia-keeps-killing 15.12.2020 15:12

@fluffy Не беспокойтесь, я был так же сбит с толку, как и вы, я ожидаю! Приносим извинения за публикацию «древней» ссылки на JavaDoc, которая только еще больше запутала ситуацию. Мы добрались туда в конце концов.

stridecolossus 15.12.2020 15:13

Это не то, что вы можете легко сделать.

Возможно, вы знаете, что Object[] на самом деле просто заполнен целыми числами, а это значит, что его можно привести, верно?

Проблема в том, что переменная «объекты» все еще существует. И в Object[] вам разрешено помещать любой Object. Итак, после вашего приведения кто-то может сделать что-то вроде:

objects[0] = "some string";

Так что же тогда должно произойти? Должен ли ваш int[] внезапно стать недействительным, поскольку теперь он содержит строку? Следует ли запрещать вводить данные, отличные от целых чисел, в objects, что обычно позволяет это делать?

Кастинг просто означает, что вы указываете на одно и то же, но смотрите на это по-разному. Что вам нужно сделать, так это преобразовать его. На это уже есть ответ:

java-преобразование массива строк в массив целых чисел

Так что простой кастинг здесь не поможет.

Обновление: ответ @stridecolossus, вероятно, так же хорош, как и тот, на который я ссылался.

Поскольку PriorityQueue реализует Collection , вы можете использовать поток для перебора его элементов и сопоставления их с int:

PriorityQueue<Integer> pq = new PriorityQueue<>(Arrays.asList(1, 2, 5));

int[] arr = pq.stream().mapToInt(Integer::intValue).toArray();

System.out.println(Arrays.toString(arr)); // [1, 2, 5]

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