Java Byte Array Set

I have a HashSet byte[] , and I would like to check if this byte[] . The problem is that Java seems to be testing if the byte[] instances are the same, and not checking if the actual values ​​in the byte arrays are the same.

In other words, consider the following code:

 public class Test { public static void main(String[] args) { java.util.HashSet<byte[]> set=new java.util.HashSet<byte[]>(); set.add(new String("abc").getBytes()); System.out.println(set.contains(new String("abc").getBytes())); } } 

This code outputs false , and I would like to print true . How can I do it?

+6
java set
source share
5 answers

You can wrap each byte array using ByteBuffer.wrap , which will provide you with the correct equals and hashCode values. Just be careful what methods you call in ByteBuffer (so you don't modify the array or advance its pointer).

+7
source share

You can avoid wrappers and a silly hash problem (hey, the standard thing, for example, byte [] does not have hashCode?):

Use TreeSet instead of HashSet and provide a byte [] comparator during instance creation:

  Set<byte[]> byteATreeSet = new TreeSet<byte[]>(new Comparator<byte[]>() { public int compare(byte[] left, byte[] right) { for (int i = 0, j = 0; i < left.length && j < right.length; i++, j++) { int a = (left[i] & 0xff); int b = (right[j] & 0xff); if (a != b) { return a - b; } } return left.length - right.length; }}); 

If you get the HashSet b byte [] from another place, initialize your variable a before TreeSet, and then use a.addAll (b); Thus, even if b contains duplicates, a does not.

+2
source share

You can define your own wrapper class, but probably the easiest task is to wrap the arrays in ArrayLists and use a HashSet<ArrayList> .

+1
source share

You can create a ByteArray class that wraps byte arrays and equality tests the way you want. Then you will have Set<ByteArray> .

+1
source share

Modern (as the solution is now)

 import com.google.common.collect.ImmutableSet; import java.nio.ByteBuffer; import java.util.Set; import static com.google.common.base.Charsets.UTF_8; import static java.nio.ByteBuffer.wrap; public class Scratch { public static void main(String[] args) { final Set<ByteBuffer> bbs = ImmutableSet.of(wrap("abc".getBytes(UTF_8)).asReadOnlyBuffer()); System.out.println("bbs.contains(ByteBuffer.wrap(\"abc\".getBytes(Charsets.UTF_8))) = " + bbs.contains(wrap("abc".getBytes(UTF_8)).asReadOnlyBuffer())); } } 

NOTES:

You should never convert String to byte[] without providing a Charset , the results become runtime based on the standard default Charset , which is usually not good and may change.

.asReadOnlyBuffer() is important!

Creates a new, read-only byte buffer that shares this buffer contents. The contents of the new buffer will correspond to the contents of this buffer. Changes to this contents of the buffer will be visible in the new buffer; however, the new buffer itself will be read-only and will not allow the shared content to be modified.

The position, limit, and label values ​​of the two buffers will be independent.

The new values ​​for buffer capacity, limit, position and label will be identical to the values ​​of this buffer. If this buffer itself is read-only, then this method behaves exactly the same as the duplication method.

0
source share

All Articles