converting 'int' to 'long' or accessing too long array with 'long'
Let's say I have an array that is long enough to access any of its index with int
, is there any way to access the index of such an array with long
? And how the Java开发者_Python百科 handle this kind of array? Example:
int[] a = new int[]{1,5,2,4........9,2,1}
Assume in the above array that 9,2,1
are at indices that are beyond the range of int
(231).
How would I access these elements?
You wouldn't - array indexes are always int
values in Java. It doesn't allow for an array with more than Integer.MAX_VALUE
elements.
The length of an array is represented by the length
field, which is of type int
. Therefore it is impossible to create an array with a length greater than Integer.MAX_VALUE
.
The spec doesn't explicitly call this out, but you can infer it from the types involved.
You can't have a that long array. But this idea has been proposed for the project coin.
Arrays must be indexed by
int
values;short
,byte
, orchar
values may also be used as index values because they are subjected to unary numeric promotion (§5.6.1) and becomeint
values. An attempt to access an array component with along
index value results in a compile-time error.
Resources :
- JLS - Array Access
- JLS - Array Creation Expressions
- Project coin - Large array V1 - V2
As others mentioned, the length and index values must be ints. If you really need this, there are workarounds though. For instance, you could have an array of very big int arrays. You could then do some modulo arithmetic on a long to determine which array you want and which index in that array is needed.
You'd need a custom data structure, try this:
/**
* 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;
}
}
精彩评论