はじめに
Java で HashMap のキーに byte[] 配列を利用したら, key を put しても containsKey で key がないよといわれてしまった.
static void testbyteMap () {
Map<byte[], Integer> map = new HashMap<byte[], Integer>();
byte[] key = {1,2,3};
byte[] key2 = {4,5,6};
byte[] key3 = {1,2,3};
map.put (key,1);
map.put (key2,2);
System.out.println (map.containsKey (key));
System.out.println (map.containsKey (key2));
System.out.println (map.containsKey (key3));
}
結果
true
true
false
調査
どうも配列を入れても, うまく検出できないようだ.
同一オブジェクトだと, 大丈夫だが, 値が同じでも違うオブジェクトだとだめ.
static void testIntMap () {
Map<int[], Integer> map = new HashMap<int[], Integer>();
int[] key = {1,2,3};
int[] key2 = {4,5,6};;
int[] key3 = {1,2,3};;
map.put (key,1);
map.put (key2,2);
System.out.println (map.containsKey (key));
System.out.println (map.containsKey (key2));
System.out.println (map.containsKey (key3));
}
解決策
原因は, byte[] が 大小比較できないから.
Stack Overflow によると
- byte[] を String に変換
- byte[] をを List<Byte>に変換
- equals と hashmap を実装した ラッパーデータ型を作成
String 変換を試す
一番お手軽なのは, String 変換か?
static void testStringMap () throws UnsupportedEncodingException {
Map<String, Integer> map = new HashMap<String, Integer>();
byte[] key = {1,2,3};
byte[] key2 = {4,5,6};
byte[] key3 = {1,2,3};
String keyStr = new String (key, "UTF-8");
String keyStr2 = new String (key2, "UTF-8");
String keyStr3 = new String (key3, "UTF-8");
map.put (keyStr,1);
map.put (keyStr2,2);
System.out.println (map.containsKey (keyStr));
System.out.println (map.containsKey (keyStr2));
System.out.println (map.containsKey (keyStr3));
}
static void testStringMap2 () throws UnsupportedEncodingException {
Map<String, Integer> map = new HashMap<String, Integer>();
byte[] key = {1,2,3};
byte[] key2 = {4,5,6};
byte[] key3 = {1,2,3};
String keyStr = Arrays.toString (key);
String keyStr2 = Arrays.toString (key2);
String keyStr3 = Arrays.toString (key3);
map.put (keyStr,1);
map.put (keyStr2,2);
System.out.println (map.containsKey (keyStr));
System.out.println (map.containsKey (keyStr2));
System.out.println (map.containsKey (keyStr3));
}
結果
これで OK.
true
true
true