-1

I'm trying to add some values to a map as

Map<byte[], byte[]> samplerMap = new HashMap<>();
samplerMap.put(Bytes.toBytes("key"), Bytes.toBytes("value"));

To fetch the value from map,

samplerMap.get(Bytes.toBytes("key"))

When I'm debugging this, I'm getting a null value. Are there any special case when using a byte[] as a key of a map. How may I fix this?

codebot
  • 2,540
  • 3
  • 38
  • 89

2 Answers2

1

You can't use an array as a key of a HashMap since arrays don't override the default implementation of equals and hashCode. Therefore two different array instances that contain the exact same elements will be considered as different keys.

You can use a List<Byte> as key instead.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • While you _can_ use `List`, the overhead is rather awful (probably over 800% on a 64-bits JVM), though I don't know whether this matters for OP's use case. Doesn't Java have something like [`com.google.protobuf.ByteString`](https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/ByteString) built in yet? – Thomas Jun 15 '18 at 08:05
1

The problem is that two byte[] use the Object.hashCode, which tests for the instance of the object. Two array instances as created by new byte[...] will yield two different hash codes, keys, and hence almost always null is returned.

Furthermore equals does not work too, hence byte[] as key is no option.

You could use the string itself, as you are actual doing "key".getBytes(StandardCharsets.UTF_8).

Or create wrapper class:

public class ByteArray {
    public final byte[] bytes;
    public ByteArray(byte[] bytes) {
        this.bytes = bytes;
    }
    @Override
    public boolean equals(Object rhs) {
        return rhs != null && rhs instanceof ByteArray
            && Arrays.equals(bytes, ((ByteArray)rhs).bytes);
    }
    @Override
    public int hashCode() {
        return Arrays.hashCode(bytes);
    }
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138