在java中使用long as ArrayList索引

我正在编写这个java程序,使用Sieve of Eratosthenes找到所有素数达到num,但是当我尝试编译时,它说我不能使用long var作为数组索引,并且它期望一个int var in它的地方。 但我会使用大数字,所以我不能使用int。 我能做什么?

import java.util.*; import java.lang.*; public class t3{ public static void main(String[] args){ long num = 100; //declaring list and filling it with numbers ArrayList numlist = new ArrayList(); for(long x=2 ; x<num ; x++){ numlist.add(new Long(x)); } //sieve or eratosthenes for(long x=0 ; x<Math.sqrt(num) ; x++){ for(long y=x+1 ; y<numlist.size() ; y++){ if(numlist[y]%numlist[x] == 0){ numlist.remove(y); } } } //print list for(Object item : numlist){ System.out.println((Long)item); } } } 

我不确定为什么你的代码会编译开始。

你不应该在数组列表中使用[]来访问成员。 arraylist只是一个内部存储在数组中的列表。 您必须使用列表获取操作(仍然是O(1))。 写numlist [index]意味着你在numlist中有一个对象数组。 您不能像在C ++中一样覆盖[]操作。

另外,Java中的int是32位。 有一个长度大于2 ^ 32的数组(所以你需要长索引)是不太可能的,我甚至不确定规范允许它。

通过32位signed int索引实现long [],你可以处理16GB的RAM。

如果你真的很认真地使用筛子来获得大质量数,那么你现在就不会想到几件事:

  • boxed longs的ArrayList
  • 使用[]像Uri提到
  • 没有系统地分页到磁盘

Java规范将数组限制为最多Integer.MAX_VALUE个元素。 虽然List可能包含更多元素 (通常对于Collection s也是如此),但您只能使用int索引添加/获取/删除/设置它们。

假设你有很多元素的内存(我认为这不太可能),你可以编写自己的数据结构,包括“连接”数组。 get()set()方法将获取一个long索引并找出该数组中相应的数组和int索引。

此外,我建议使用布尔值来表示每个数字的状态,而不是显式地存储/删除每个数字。 这样会更好,因为(1)布尔占用的空间少于长,(2)在元素移除期间移位元素(如在ArrayList所做的那样)可能很昂贵。

至少java数组的理论最大大小是Integer.MAX_VALUE。 这是因为数组索引的类型是根据spec和int。 实际上,这取决于你的记忆力。

因此,如果您的算法确实依赖于拥有如此大的数组,那么您对java数组运气不利。

因为我怀疑你需要所有的空间,你可以编写自己的集合类,它像一个数组,但不需要那么多的内存。 它会破坏地址空间中的整体(可以这么说)。 当然,这可能会改变您期望从算法中运行时的行为。

有人建议通过Project Coin( http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html )向Java添加长索引数组,尽管没有接受或安排任何内容。

简单的解决方案:考虑到代码示例中的num绝不会大于100,只需将其类型更改为int

但其他人提到的关于地址空间的观点也是好点。

jScience库有一个名为Float64Vector的大型向量。 虽然我从未使用过这个类,但它可能符合您的需求。 没有保证。

编辑:Zach Scrivena在评论中指出Float64Vector的尺寸符合整数。 我有所纠正。