• このエントリーをはてなブックマークに追加

スポンサードリンク

はじめに

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