如何使用Java制作真正大的布尔数组?

如何使用Java制作真正大的布尔数组?,java,boolean,Java,Boolean,当我尝试使用Java创建一个非常大的布尔数组时,例如: boolean[] isPrime1 = new boolean[600851475144]; 我得到一个可能的精度误差损失 它太大了吗?数组索引是int,而不是long,因此您的“数组”太大,无法放入数组中。其中一个java集合类可能更适合。没关系-Collection.size()也会返回一个int,所以Collection也不能存储超过Integer.MAX\u VALUE的项。考虑使用。Um。。。这将是大约70 GB的布尔

当我尝试使用Java创建一个非常大的布尔数组时,例如:

    boolean[] isPrime1 = new boolean[600851475144];
我得到一个可能的精度误差损失


它太大了吗?

数组索引是int,而不是long,因此您的“数组”太大,无法放入数组中。其中一个java集合类可能更适合。没关系-Collection.size()也会返回一个int,所以Collection也不能存储超过
Integer.MAX\u VALUE
的项。

考虑使用。

Um。。。这将是大约70 GB的布尔值。不行。不行。

您可以使用一个长数组,封装在一个类中,该类将处理数组上的所有操作。类似于您自己的位集实现。

要存储6000亿位,您需要75 GB的绝对最小地址空间!祝你好运

更糟糕的是,Java规范没有指定一个
boolean
数组将为每个元素使用一位内存,它可以()使用更多


在任何情况下,我都能从中认出这个数字。如果它需要那么多内存,那就是你做错了…

问题是你使用的数组大小是long值还是int值。Java不支持数组长度超过int的最大值。Java将您的长度视为long,因为您指定的大小超过int的最大值,但适合long。因此,它必须将长度转换回int以创建数组。从long->int的转换产生了您看到的警告,为什么不将值存储在文件中,然后查找文件中的位置并提取正确的值呢。正如其他人所说,这是70GB的数据。在大多数情况下,你甚至无法将其保存在内存中。如果要将数据存储到文件中,甚至可以在使用逐位运算符存储和检索数据时查看各个位,以节省存储空间


此外,由于素数的数量随着数字的大小而减少,因此最好将素数本身按顺序存储在文件中,然后对该数字进行二进制搜索,以查看它是否是素数之一。

数组中有哪些值?
对于如此大的数字,我想它将是一个稀疏数组,所以也许最好使用一个映射/列表,只分配空间并存储一个1值的值一点。如果大多数值都是1,则为0。

由于您试图以错误的方式解决Euler问题#3,这里有一个提示:您应该找到一个数的所有素数因子,而不是低于某个限制的所有素数


顺便说一句:这个特殊的Euler问题可以使用非常少量的RAM来解决。

ApacheActiveMQ有一个名为BitArrayBin的数据结构。这用于确定消息是否重复。消息ID是生产者ID和序列ID的组合。 每个生产者将有一个BitArrayBin来跟踪其序列ID。一旦找到给定生产者的BitArrayBin,它就会将序列ID设置为BitArrayBin的长值

 oldValue = bitArrayBin.setBit(sequenceId, true)
 if (oldVlaue) {
   "message is duplicated"
 }
该方法返回旧值

如果y是长索引,则它用于在bin索引及其偏移量处进行推导

y = bin index * 64 + offset
BitArrayBin只不过是许多箱子的支架,在建造过程中可以定义箱子的大小。每个bin包含一个长变量来存储位,因此它最多可以存储64个布尔值

位屏蔽用于设置位,然后获取其值

这个类没有太多文档。您需要浏览其源代码以了解其内部结构


get/set操作的位集索引是int,而不是long。位集实际上只将所需的大小减少了1/8。提问者使用的值远大于数组长度最大值的8倍。没错,位集无法获得所需的大小。不过,在这种情况下,它仍然是一个很好的集合。@Alnitak-我意识到了这一点,并在你发表评论时进行了编辑。从技术上讲,一个集合可能存储多个Integer.MAX\u值元素——发生这种情况时,size()只返回Integer.MAX\u值。不知道为什么会被否决,因为在Java中,这几乎是在单个数据结构中接近该位数的唯一方法(假设您有一个64位虚拟机能够处理这么多内存)。至少需要3个long数组才能打包这么多的位。是的,我第一次尝试时被误导了。谢谢你的提示。至少我从这些评论中学到了一点。它可以。。。在TB系统上。