Большой массив типа «int» необходимо передать в общий массив и коллекции.

Я генерирую большие массивы (размер> 1000) с элементами типа int из функции. Мне нужно передать этот массив в массив универсального типа, но, поскольку массив универсального типа не принимает массивы примитивного типа, я не могу этого сделать.

Я боюсь использовать массив типа Integer, так как это будет дорого с точки зрения создания, производительности, используемого пространства (массив 12-байтовых объектов) при использовании массивов большого размера. Более того, он создаст неизменяемые Integer , когда мне нужно будет выполнить некоторые операции добавления элементов массива.

Что было бы лучшим способом пойти с ?

РЕДАКТИРОВАТЬ Просто чтобы устранить некоторую путаницу, мне нужно передать int[] методу типа подписи: void setKeys(K... keys).


person Rajat Gupta    schedule 18.03.2011    source источник
comment
@Marcos Можете ли вы привести пример кода, чтобы прояснить, что вы пытаетесь сделать?   -  person Melv    schedule 18.03.2011
comment
Я думаю, что у него есть такой метод, как public void ‹T extends Object› processArray(T[] t), но, конечно, он не может использовать с ним целые числа.   -  person MeBigFatGuy    schedule 18.03.2011
comment
Я хотел бы узнать больше о том, кому вы его передаете. Если это похоже на пример MeBigFatGuy, вы застряли. Но, возможно, API, который вы вызываете, принимает Iterable или Iterator - если это так, вы можете реализовать это поверх int[] без фактической материализации всех целых чисел одновременно. Или, может быть, вы могли бы передать свой массив в серии небольших вызовов.   -  person Vance Maverick    schedule 18.03.2011
comment
Я хочу передать int[] этой функции: public Query<K> setKeys(K... keys);   -  person Rajat Gupta    schedule 18.03.2011
comment
Ну, тогда все значения должны быть Integer на момент вызова.   -  person Vance Maverick    schedule 18.03.2011
comment
также обязательно в том случае, когда у меня public Query<K> setKeys(K[] keys); правильно?   -  person Rajat Gupta    schedule 18.03.2011


Ответы (5)


Я хочу передать int[] этой функции: public Query<K> setKeys(K... keys);

Я предполагаю, что вы имеете в виду, что int[] должен быть набором ключей... а не одним ключом.

Это невозможно. Параметры типа универсального типа должны быть ссылочными типами. Ваш вариант использования требует, чтобы K было int.

У вас есть два варианта:

  • использовать Integer (или изменяемый класс держателя int) и заплатить штраф за производительность, или
  • отказаться от использования дженериков и изменить подпись этого метода.

Между прочим, класс Integer хранит в кэше Integer объектов для небольших int значений. Если вы создаете свои объекты с помощью Integer.valueOf(int), есть большая вероятность, что вы получите ссылку на уже существующий объект. (Конечно, это работает только потому, что объекты Integer неизменяемы.)

person Stephen C    schedule 18.03.2011
comment
отказаться от использования дженериков и изменить сигнатуру этого метода.: к сожалению, это не в моих руках, то есть из внешней библиотеки - person Rajat Gupta; 18.03.2011
comment
@Маркос - ну, вот твой ответ. Вы должны использовать Integer или изменяемую альтернативу. - person Stephen C; 18.03.2011

Если ваши массивы состоят из порядка 1000 (или даже 10 000 или 100 000) элементов, разница в стоимости с точки зрения памяти и производительности, вероятно, не будет заметной, если только вы не обрабатываете массивы тысячи раз каждый. Напишите код с помощью Integer и оптимизируйте позже, если у вас возникнут проблемы с производительностью.

person Jim Garrison    schedule 18.03.2011

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

person Melv    schedule 18.03.2011
comment
Например. MutableInt из Apache Commons :) - person Piotr Findeisen; 20.03.2011

Если вам действительно нужно беспокоиться о влиянии упаковки/распаковки целых чисел на производительность, вы можете подумать о GNU Trove, особенно их TIntArrayList. Он позволяет имитировать функциональность ArrayList<Integer> при поддержке примитивов. Тем не менее, я не уверен, что вам это нужно, и я не уверен, что это именно то, что вы ищете.

person Michael McGowan    schedule 18.03.2011
comment
хорошая идея, но она не сработает, если ему нужно передать ее функции, которая принимает K[], как он говорит в своих комментариях - person newacct; 18.03.2011

Если вы не хотите, чтобы целые числа были постоянно упакованы, вы можете передать результат Ints.asList() из библиотеки Google Collections (http://guava-libraries.googlecode.com/svn/tags/release08/javadoc/com/google/common/primitives/Ints.html#asList%28int...%29), который будет List<Integer> поддерживаемым массивом. Значения будут упаковываться по мере доступа к ним, поэтому это имеет смысл только в том случае, если к значениям не обращаются много раз.

person SimonC    schedule 20.03.2011
comment
Как указал @newacct для другого ответа: хорошая идея, но она не сработает, если ему нужно передать ее функции, которая принимает K[], как он говорит в своих комментариях. - person Piotr Findeisen; 20.03.2011