Reputation: 213
Can anyone help me to know how can I have a "Set" of Bytes in Java? Thank you
Upvotes: 2
Views: 4267
Reputation: 4782
You can have a Set<Byte>
but not a Set<byte>
, Byte being an object and byte a primitive. If you create a set of Byte then you can add byte values to it and they will be auto-boxed to Bytes on the fly, giving you the expected result.
Set<Byte> byteSet = new HashSet<Byte>();
byte b1 = 1;
Byte b2 = 1;
byte b3 = 2;
byteSet.add(b1);
byteSet.add(b2);
byteSet.add(b3);
System.out.println(byteSet);
Outputs:
[1, 2]
It should be noted that, although this method is quite clear and uses the familiar Java Collections Framework, the auto-boxing can become a performance issue if you are doing lots of work on the set -- but to see this effect you are really going to have to hammer it.
More performant alternatives have been suggested, like java.util.BitSet
by polygenelubricants, or Jon Skeet's array solution.
Upvotes: 3
Reputation: 383676
Set<Byte>
option from the Java Collections FrameworkIf you want to harness the Java Collections Framework, you can have a java.util.Set<Byte>
. Unfortunately Java generics doesn't work with primitive. java.lang.Byte
is the box type for byte
. Perhaps an implementation that you can use is a TreeSet
; it is a SortedSet
, so you can sort the (boxed) byte
by their natural ordering.
BitSet
option for performanceAnother option is a java.util.BitSet
. This is a very time and space efficient data structure that implements set representation using bits, i.e. an int i
is "in the set" if bit i
is set.
BitSet
is not part of the Java Collections Framework.
Here's an example usage:
BitSet bytes = new BitSet();
bytes.set(3);
bytes.set(7);
bytes.set(11);
bytes.set(11);
bytes.set(1000);
System.out.println(bytes);
// {3, 7, 11, 1000}
System.out.println(bytes.cardinality()); // 4
System.out.println(bytes.get(10)); // false
Note that you may set
bits that are out of the byte
range.
In fact, you can't directly set
all bits in the byte
range, since byte
is a signed datatype in Java. You can use bit masking to convert any byte
to an int
in the 0..255
range as follows:
byte b = -1;
// bytes.set(b); // throws IndexOutOfBoundsException
bytes.set(b & 0xFF);
System.out.println(bytes);
// {3, 7, 11, 255, 1000}
You can then iterate over all byte
in the set as follows:
for (int i = -1; (i = bytes.nextSetBit(i + 1)) != -1; ) {
byte b = (byte) i;
System.out.println(b);
}
// 3, 7, 11, -1, -24
Note that because of the byte [-128,127]
to int [0,255]
mapping, negatives come after positives. BitSet
also facilitates efficient set operations against other BitSet
, like or
, and
, xor
, equals
, intersects
, etc.
byte
is signed
byte
is -128..127
, not 0..255
.Upvotes: 10
Reputation: 11535
If you often need collections containing primitive types, have a look at the Primitive Collections for Java. It implements the main types of collections for each primitive type, which should be faster and more memory efficient than using the wrapper Byte class.
Other similar libraries are available.
Upvotes: 1
Reputation: 1499770
As polygenelubricants says, you can have a Set<Byte>
. Another simple alternative would be to have:
boolean[] byteSet = new boolean[256];
This would be very efficient to check or set each value - and iterating over the set of values would only take 256 iterations anyway :)
Upvotes: 4