Red Lion
Red Lion

Reputation: 213

Java Set of Bytes

Can anyone help me to know how can I have a "Set" of Bytes in Java? Thank you

Upvotes: 2

Views: 4267

Answers (4)

Tom
Tom

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

polygenelubricants
polygenelubricants

Reputation: 383676

Set<Byte> option from the Java Collections Framework

If 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.

See also

Related questions


BitSet option for performance

Another 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.

Related questions

Upvotes: 10

Nick H
Nick H

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

Jon Skeet
Jon Skeet

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

Related Questions