在 java 中使用 long as ArrayList 索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/459643/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:52:50  来源:igfitidea点击:

Using a long as ArrayList index in java

javaarraylist

提问by liewl

I am writing this java program to find all the prime numbers up to num using the Sieve of Eratosthenes, but when I try to compile, it says I can't use a long var as an array index, and it expects an int var in its place. But I'll be working with large numbers, so I can't use int. What can I do?

我正在编写这个 java 程序,以使用 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<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);
        }
    }
}

采纳答案by Uri

I'm not sure why your code would compile to begin with.

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

You're not supposed to use [] in an array list to access members. An arraylist is merely a list that is internally stored in an array. You have to use the list get operation (which would still be O(1)). Writing numlist[index] means that you have an array of objects in numlist. You cannot override the [] operation as in C++.

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

In addition, an int is 32 bits in Java. Having an array of length greater than 2^32 (so you would need long indices) is unlikely and I'm not even sure the specification allows it.

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

回答by wowest

Realize that with a 32-bit signed int index to a long[] you're addressing 16GB of RAM.

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

If you're really serious about getting to big primes with the sieve, you're not going to get away with several things in your current impl:

如果您真的很想用筛子获得大素数,那么您将不会在当前的实现中逃脱以下几件事:

  • ArrayList of boxed longs
  • Using [] like Uri mentions
  • Not systematically paging to disk
  • 盒装多头的ArrayList
  • 使用 [] 就像 Uri 提到的那样
  • 没有系统地分页到磁盘

回答by tcurdt

At least the theoretical maximum size of java arrays is Integer.MAX_VALUE. This is because the type of the array index is according to the specan int. In reality it depends on your memory though.

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

So if your algorithm really depends on having such a large array you are out of luck with java arrays.

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

As I doubt you will need all the space you could write your own collection class that acts like a array but does not need as much memory. It would collapse the wholes in the address space (so to speak). Of course this might change the runtime behavior you are expecting from the algorithm.

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

回答by matt b

The simple solution: considering that numis never larger than 100 in your code sample, just change it's type to int.

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

But the points others have mentioned about address space are also good points.

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

回答by WolfmanDragon

the jScience Library has a large vector called Float64Vector. While I have never used this Class it might fit your needs. No promises.

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

EDIT: Zach Scrivena pointed out in the comments that the Float64Vector is dimensioned to ints. I stand corrected.

编辑:Zach Scrivena 在评论中指出 Float64Vector 的尺寸为整数。我站着纠正。

回答by Zach Scrivena

The Java specificationlimits arrays to at most Integer.MAX_VALUE elements. While a Listmay contain more elements(this is true for Collections in general), you can only add/get/remove/setthem using an intindex.

Java规范至多Integer.MAX_VALUE的元件限制了阵列。虽然 aList可能包含更多元素一般情况下Collections也是如此),但您只能使用索引添加/获取/删除/设置它们。int

Assuming you have the memory for that many elements (very unlikely I think), you could write your own data structure consisting of "concatenated" arrays. The get()and set()methods would take a longindex and figure out the corresponding array and intindex within that array.

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

Also, I would suggest using booleans to represent the state of each number, instead of storing/removing each number explicitly. This would be better because (1) booleans take less space than longs, and (2) shifting elements (as done in ArrayList) during element removal can be expensive.

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

回答by Alex Miller

There have been proposals to add long-indexed arrays to Java via Project Coin ( http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000869.html) although nothing has been accepted or scheduled.

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