How do you make REALLY large boolean arrays using Java?

限于喜欢 提交于 2020-01-02 01:23:08

问题


When I try to make a very large boolean array using Java, such as:

    boolean[] isPrime1 = new boolean[600851475144];

I get a possible loss of precision error?

Is it too big?


回答1:


To store 600 billion bits, you need an absolute minimum address space of 75 gigabytes! Good luck with that!

Even worse, the Java spec doesn't specify that a boolean array will use a single bit of memory for each element - it could (and in some cases does) use more.

In any case, I recognise that number from Project Euler #3. If it needs that much memory, you're doing it wrong...




回答2:


Consider using a BitSet.




回答3:


Since you're attempting to solve Euler-problem #3 the wrong way, here's a hint: You're supposed to find all the prime factors of a number, not all the prime numbers below a certain limit.

BTW: This particular Euler-problem can be solved using a very small amount of RAM.




回答4:


An array index is an int, not a long, so your "array" is too big to fit into an array. One of the java Collection classses might be more suited. Never mind - Collection.size() returns an int as well, so Collection can't store more than Integer.MAX_VALUE items either.




回答5:


Um... that would be about 70GB worth of booleans. Not gonna work. No way.




回答6:


The problem is you are using a long value vs. an int value for the size of the array. Java does not support array lengths longer that the maximum value of an int. Java is treating your length as a long because the size you specified exceeds the maximum value for an int but fits within a long. Hence it must convert the length back to an int to create an array. The conversion from long -> int is producing the warning you are seeing




回答7:


You can use an array of longs, encapsulated in a class that would handle all the operations on the array. Something like your own implementation of BitSet.




回答8:


Why not just store the values in a file, and then seek to the position in the file and pull up the right value. Like others have stated, that's 70GB of data. In most cases, you wouldn't even be able to hold that in memory. If you're going to store it to a file, you could even look at individual bits when storing and retrieving the data using bitwise operators to save on storage space.

Also, since the number of primes decreases with the size of the numbers, it's probably better just to store the prime numbers themselves in the file, in order, and then do a binary search for the number to see if it is one of the primes.




回答9:


What values do you have in the array? For a such large number I guess it's going to be a sparse array so maybe it would be best to use a Map/List and just allocate space and store a value for a 1 value for a bit. Or for a 0 value if most of your values will be 1.




回答10:


Apache ActiveMQ has a datastructure called BitArrayBin. This is used to find out whether a message is duplicated. A message ID is a combination of producer ID and sequence ID. Each producer will have a BitArrayBin to track its sequence IDs. Once it finds out the BitArrayBin for the given producer, it sets the sequence ID which is a long value to the BitArrayBin.

 oldValue = bitArrayBin.setBit(sequenceId, true)
 if (oldVlaue) {
   "message is duplicated"
 }

The method returns the old Value.

If y is the long index, it is used to derive at a bin index and an offset into it.

y = bin index * 64 + offset

BitArrayBin is nothing but a holder for many bins where the size can be defined during its construction. Each bin contains a long variable to store the bits so so it can store up to 64 boolean values.

Bit masking is used to set the bit, and then, get it's value.

This class doesn't have much documentation. You need to go through its source code to know the internals.



来源:https://stackoverflow.com/questions/458489/how-do-you-make-really-large-boolean-arrays-using-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!