你如何使用Java制作真正的大型布尔数组?
当我尝试使用Java创建一个非常大的布尔数组时,例如:
boolean[] isPrime1 = new boolean[600851475144];
我可能会丢失精度误差?
太大了吗?
要存储6000 亿位,您需要一个75 千兆字节的绝对最小地址空间! 祝你好运!
更糟糕的是,Java规范并未指定boolean
数组将为每个元素使用单个内存位 – 它可能( 在某些情况下 )使用更多。
无论如何,我从Project Euler#3中识别出这个数字。 如果它需要那么多记忆,那你做错了……
考虑使用BitSet 。
由于你试图以错误的方式解决欧拉问题#3,这里有一个提示:你应该找到一个数字的所有素因子 ,而不是所有低于某个限制的素数 。
顺便说一句:这个特殊的欧拉问题可以用很少量的RAM来解决。
数组索引是一个int,而不是long,所以你的“数组”太大而不适合数组。 其中一个java Collection类可能更适合。 没关系 – Collection.size()也返回一个int,因此Collection也不能存储超过Integer.MAX_VALUE
项。
嗯…那将是大约70GB的布尔值。 不会工作。 没门。
问题是你使用长值而不是数组大小的int值。 Java不支持比int的最大值更长的数组长度。 Java将您的长度视为long,因为您指定的大小超过int的最大值但适合long。 因此,它必须将长度转换回int以创建数组。 从long – > int的转换产生了你所看到的警告
您可以使用一个long数组,封装在一个可以处理数组上所有操作的类中。 像你自己的BitSet实现。
为什么不将值存储在文件中,然后查找文件中的位置并提取正确的值。 像其他人所说,这是70GB的数据。 在大多数情况下,您甚至无法将其保留在内存中。 如果您要将其存储到文件中,您甚至可以在使用按位运算符存储和检索数据时查看单个位以节省存储空间。
此外,由于素数的数量随着数字的大小而减少,所以最好只是将素数本身按顺序存储在文件中,然后对数字进行二进制搜索以查看它是否是素数之一。
你在数组中有什么价值? 对于如此大的数字,我猜它将是一个稀疏数组,所以也许最好使用Map / List并且只是分配空间并为一个值存储一个值。 如果您的大多数值为1,则为0。
Apache ActiveMQ有一个名为BitArrayBin的数据结构。 这用于确定消息是否重复。 消息ID是生产者ID和序列ID的组合。 每个生产者都有一个BitArrayBin来跟踪它的序列ID。 一旦找到给定生成器的BitArrayBin,它就会将序列ID设置为BitArrayBin的long值。
oldValue = bitArrayBin.setBit(sequenceId, true) if (oldVlaue) { "message is duplicated" }
该方法返回旧值。
如果y是长索引,则它用于导出bin索引和偏移量。
y = bin index * 64 + offset
BitArrayBin只是许多箱子的支架,其大小可以在其构造期间定义。 每个bin包含一个long变量来存储这些位,因此它可以存储多达64个布尔值。
位屏蔽用于设置位,然后获取它的值。
这个类没有太多文档。 您需要通过其源代码来了解内部。