Преобразование 'int' в 'long' или доступ к слишком длинному массиву с 'long'
Скажем, у меня есть массив, достаточно длинный для доступа к любому из его индексов с помощью int
, есть ли способ получить доступ к индексу такого массива с помощью long
? И как Java обрабатывает такой массив? Пример:
int[] a = new int[]{1,5,2,4........9,2,1}
Предположим, что в приведенном выше массиве 9,2,1
находятся в индексах, выходящих за пределы диапазона int
(2 31).
Как я могу получить доступ к этим элементам?
Ответы
Ответ 1
Вы не указали - индексы массива всегда являются значениями int
в Java. Он не допускает массив с более чем Integer.MAX_VALUE
элементами.
Длина массива представлена полем length
, которое имеет тип int
. Поэтому невозможно создать массив длиной более Integer.MAX_VALUE
.
spec явно не вызывает этого, но вы можете сделать вывод о нем из соответствующих типов.
Ответ 2
У вас не может быть такого длинного массива. Но эта идея была предложена для монеты проекта.
Массивы должны индексироваться значениями int
; Значения short
, byte
или char
также могут использоваться в качестве значений индекса, поскольку они подвергаются унарной цифровой рекламе (§5.6.1) и становятся int
значениями. Попытка доступа к массиву с индексом long
приводит к ошибке времени компиляции.
Ресурсы:
Ответ 3
Как упоминалось выше, значения длины и индекса должны быть ints. Если вам это действительно нужно, есть обходные пути. Например, у вас может быть массив очень больших массивов int. Затем вы можете выполнить некоторую арифметику по модулю, чтобы определить, какой массив вы хотите, и какой индекс в этом массиве необходим.
Ответ 4
Вам понадобится настраиваемая структура данных, попробуйте следующее:
/**
* Because java uses signed primitives only the least significant 31 bits of an int are used to index arrays,
* therefore only the least significant 62 bits of a long are used to index a LongArray
*
* @author aaron
*/
public class LongArray<Element> {
//inclusive
public static final long maximumSize = (~0)>>>2;//0x 00 FF FF FF FF FF FF FF
public static final long minimumSize = 0;
//Generic arrays are forbidden! Yay dogma!
private Object[][] backingArray;
private static int[] split(long L) {
int[] rtn = new int[2];
rtn[1] = Integer.MAX_VALUE & (int)(L>>7);
rtn[0] = Integer.MAX_VALUE & (int)L;
return rtn;
}
private static long join(int[] ia) {
long rtn = 0;
rtn |= ia[0];
rtn <<= 7;
rtn |= ia[1];
return rtn;
}
private static boolean isValidSize(long L) {
return L<=maximumSize && L>=minimumSize;
}
public LongArray(long size){
if (!isValidSize(size)) throw new IllegalArgumentException("Size requested was invalid, too big or negative");
//This initialises the arrays to be only the size we need them to be
int[] sizes = split(size);
backingArray = new Object[sizes[0]][];
for (int index = 0; index<backingArray.length-1; index+=1) {
backingArray[index] = new Object[Integer.MAX_VALUE];
}
backingArray[backingArray.length-1] = new Object[sizes[1]];
}
public Element get(long index) {
int[] ia = split(index);
return (Element)backingArray[ia[0]][ia[1]];
}
public void set(long index, Element element) {
int[] ia = split(index);
backingArray[ia[0]][ia[1]] = element;
}
}