假设我有一个数组,它的长度足够长,可以使用int
访问其任何索引,是否有办法通过long
访问这种类型数组的索引?而Java如何处理这种类型的数组呢?例如:
int[] a = new int[]{1,5,2,4........9,2,1}
假设在上述数组中,
9,2,1
的索引超出了 int
(231)的范围。
我该如何访问这些元素?假设我有一个数组,它的长度足够长,可以使用int
访问其任何索引,是否有办法通过long
访问这种类型数组的索引?而Java如何处理这种类型的数组呢?例如:
int[] a = new int[]{1,5,2,4........9,2,1}
9,2,1
的索引超出了 int
(231)的范围。
我该如何访问这些元素?int
值。它不允许具有超过Integer.MAX_VALUE
元素的数组。int
的length
字段表示。因此,不可能创建长度大于Integer.MAX_VALUE
的数组。
spec没有明确说明这一点,但可以从涉及的类型推断出来。/**
* 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;
}
}
你不能有那么长的数组。但这个想法已经被提出为“项目硬币”。
数组必须由
int
值索引;short
、byte
或char
值也可以用作索引值,因为它们接受一元数值提升(§5.6.1)并成为int
值。试图使用long
索引值访问数组组件会导致编译时错误。
资源:
正如其他人所提到的,长度和索引值必须是整数。如果你真的需要这个,有一些变通方法。例如,你可以有一个非常大的整数数组的数组。然后,你可以对长整型进行一些模算术运算,以确定你想要哪个数组以及该数组中所需的索引。
List.get()
需要一个int
索引...我认为没有任何集合可以处理超过20亿个元素。 - Jon Skeet