【问题标题】:Using a long as ArrayList index in java在 java 中使用 long as ArrayList 索引
【发布时间】:2010-10-02 08:36:27
【问题描述】:

我正在编写这个 java 程序来使用 Eratosthenes 的 Sieve 查找直到 num 的所有素数,但是当我尝试编译时,它说我不能使用 long var 作为数组索引,它需要一个int var 代替它。但我将处理大量数字,所以我不能使用 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<Long> numlist = new ArrayList<Long>();
        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);
        }
    }
}

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

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

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

    另外,一个 int 在 Java 中是 32 位的。长度大于 2^32 的数组(因此您需要长索引)不太可能,我什至不确定规范是否允许。

    【讨论】:

    • 字节码只允许使用 int 大小和索引的数组,因此必须对类文件格式进行(相当大的)更改才能允许这样做。
    【解决方案2】:

    意识到使用 long[] 的 32 位有符号 int 索引,您正在处理 16GB 的 RAM。

    如果你真的很想用筛子得到大素数,那么在你当前的 impl 中,你不会逃脱一些事情:

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

    【讨论】:

      【解决方案3】:

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

      因此,如果您的算法真的依赖于拥有如此大的数组,那么您对 ​​java 数组就不走运了。

      我怀疑您是否需要所有可以编写自己的集合类的空间,该集合类的作用类似于数组,但不需要太多内存。它会折叠地址空间中的整体(可以这么说)。当然,这可能会改变您对算法的预期运行时行为。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          编辑: Zach Scrivena 在 cmets 中指出 Float64Vector 的尺寸为整数。我的立场是正确的。

          【讨论】:

          • Float64Vector 是一个“正常”大小的向量,可以容纳 Integer.MAX_VALUE 元素,正如其 getDimension() 方法所暗示的那样。
          【解决方案6】:

          Java specification 将数组限制为最多 Integer.MAX_VALUE 元素。虽然List 可能包含more elementsCollections in general 也是如此),但您只能使用int 索引来add/get/remove/set

          假设您有这么多元素的内存(我认为这不太可能),您可以编写自己的由“连接”数组组成的数据结构。 get()set() 方法将采用 long 索引并找出对应的数组和该数组中的 int 索引。

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

          【讨论】:

          • 根据合同,List 允许 int size()
          【解决方案7】:

          已经有人提议通过 Project Coin (http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html) 将长索引数组添加到 Java,但尚未接受或安排任何内容。

          【讨论】:

            猜你喜欢
            • 2012-12-11
            • 1970-01-01
            • 2013-04-20
            • 1970-01-01
            • 1970-01-01
            • 2011-01-22
            • 1970-01-01
            • 2019-11-27
            • 2014-03-10
            相关资源
            最近更新 更多