BitSet
has a stream()
method but it does not implement the Iterable
interface like other types that provide this method. Is there a specific reason for this?

- 3,042
- 3
- 31
- 37
4 Answers
None of the methods in Iterable
(foreach
, iterator
, and spliterator
) is provided in BitSet
. There is no stream()
method in Iterable
.
Furthermore the stream()
method of BitSet
does not return a stream over the bits of the bit set, but returns a stream over the indices of the bits whose values are set (which is kind of confusing TBH). Therefore, technically speaking there seems to be almost nothing in common with Iterable
.

- 71,713
- 13
- 134
- 174
One reason (not the entire reason, maybe) is that Iterable
would inefficient, because the bit indexes have to be boxed (*); the stream is able to use primitive ints.
There's an efficient way to iterate the bitset without using Iterable
, as described in the Javadoc, so it's not really necessary.
(*) However, for bitsets with size 128 or smaller, boxing would be cheap, as cached boxed instances would be used.

- 137,514
- 11
- 162
- 243
BitSet
is not a "true" member of the java collection framework, so technically, no need to implement Collection.iterator()
and provide one.
public class BitSet implements Cloneable, java.io.Serializable
More to the point, both would be ill-fitted togethoer.
BitSet are not generic, unlike java.util.Iterator; BitSet provides ad-hoc methods with special features for side-effects and random addressing, unlike Iterator.

- 2,784
- 2
- 21
- 33
Probably to avoid expensively boxing every bit to a Boolean
instance.
Looping over it using its own APIs will avoid all allocations.

- 868,454
- 176
- 1,908
- 1,964
-
could be a primitive short i guess – Fabien Benoit-Koch Jan 24 '17 at 20:35
-
1@fabienbk: No; Java does not support primitive generics. – SLaks Jan 24 '17 at 20:36
-
2Boxing to a Boolean is really cheap: there's only two of them, and they're cached. The `stream` returns `int`s representing the set bit indexes; I think OP expects the `Iterable` to do the same (except with `Integer`). – Andy Turner Jan 24 '17 at 20:36
-
Oops, you're right. Definitely the main reason then. – Fabien Benoit-Koch Jan 24 '17 at 20:38
-
Java does have PrimitiveIterator since 8, so it could have been possible I guess – Jean-François Savard Jan 24 '17 at 20:40
-
No, it's just an odd duck class that pre-dates Collections. It has methods with names that are at odds with collections conventions too (take a look at size). It's not related to performance, it's just a somewhat abandoned class. – pvg Jan 24 '17 at 20:40
-
2"a somewhat abandoned class" citation needed. In my experience, it's not abandoned, but rather only used in specific applications. – Andy Turner Jan 24 '17 at 20:42
-
@AndyTurner Look at its use in the JDK - occasional use in some older classes. The problem with it is it makes no useful performance and storage guarantees and has a weird old API. Anyone needing a bitset is likely to use something else or a newer third party implementation. – pvg Jan 24 '17 at 20:46
-
@pvg: it got additions in 1.2, 1.4, 1.7 and 1.8. That’s not the typical pattern of a “somewhat abandoned class”. The use within the JDK itself is irrelevant, I could point to lots of classes not being used within the JDK itself. And what “useful performance and storage guarantees” do you expect? The storage is one bit per bit, plus an implementation specific padding. And why should `BitSet` be the first class in the entire Java history making “performance guarantees”? – Holger Feb 28 '17 at 16:58
-
@Holger many java classes have specified performance characteristics. 'one per bit plus padding' is not really stated by the docs, even if that does happen to be the implementation. In the end, for trivial cases you're more likely to use a raw mask or an array or collection of booleans, for not-trivial cases, there are piles of other, better implementations. If you don't like 'abandoned' I guess 'vestigial' is a better word. – pvg Feb 28 '17 at 17:49