Преобразование '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;
    }

}