преобразование int в long или получение доступа к слишком длинному массиву с помощью long - PullRequest
4 голосов
/ 15 октября 2010

Допустим, у меня есть массив, который достаточно длинный для доступа к любому из его индексов с int, есть ли способ получить доступ к индексу такого массива с long? И как Java обрабатывает этот вид массива? Пример:

int[] a = new int[]{1,5,2,4........9,2,1}

Предположим, что в приведенном выше массиве 9,2,1 имеют индексы, выходящие за пределы диапазона int (2 31 ). Как бы я получил доступ к этим элементам?

Ответы [ 4 ]

5 голосов
/ 15 октября 2010

Вы бы не стали - индексы массивов всегда являются int значениями в Java. Он не допускает массив с более чем Integer.MAX_VALUE элементами.

Длина массива представлена ​​полем length, которое имеет тип int. Поэтому невозможно создать массив длиной более Integer.MAX_VALUE.

Спецификация явно не вызывает этого, но вы можете вывести ее из соответствующих типов.

0 голосов
/ 09 мая 2012

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

/**
* 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;
    }

}
0 голосов
/ 15 октября 2010

Как уже упоминалось, значения длины и индекса должны быть целыми числами. Если вам это действительно нужно, есть обходные пути. Например, вы можете иметь массив очень больших массивов int. Затем вы можете выполнить некоторую арифметику по модулю для long, чтобы определить, какой массив вам нужен и какой индекс в этом массиве необходим.

0 голосов
/ 15 октября 2010

Вы не можете иметь этот длинный массив.Но эта идея была предложена для монеты проекта.

Массивы должны быть проиндексированы значениями int;Значения short, byte или char также могут использоваться в качестве значений индекса, поскольку они подвергаются одинарному числовому продвижению (§5.6.1) и становятся значениями int. Попытка получить доступ к компоненту массива со значением индекса long приводит к ошибке времени компиляции .


Ресурсы:

...