在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的尺寸符合整数。 我有所纠正。