Voir le sujet - voyez-vous un problème avec cela? Je pourrais aussi faire new String(byte[])
et hachage de String
mais il est plus simple d’utiliser byte[]
Réponses
Trop de publicités?C'est ok aussi longtemps que vous voulez seulement référence à l'égalité pour votre clé - tableaux de ne pas mettre en œuvre "la valeur de l'égalité", dans le sens que vous auriez probablement souhaitez. Par exemple:
byte[] array1 = new byte[1];
byte[] array2 = new byte[1];
System.out.println(array1.equals(array2));
System.out.println(array1.hashCode());
System.out.println(array2.hashCode());
imprime quelque chose comme:
false
1671711
11394033
(Les chiffres réels sont sans importance; le fait qu'ils sont différents, c'est important.)
En supposant que vous avez réellement envie de l'égalité, je vous suggère de créer votre propre surcouche qui contient un byte[]
et met en œuvre l'égalité de hachage et de génération de code de façon appropriée:
public final class ByteArrayWrapper
{
private final byte[] data;
public ByteArrayWrapper(byte[] data)
{
if (data == null)
{
throw new NullPointerException();
}
this.data = data;
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof ByteArrayWrapper))
{
return false;
}
return Arrays.equals(data, ((ByteArrayWrapper)other).data);
}
@Override
public int hashCode()
{
return Arrays.hashCode(data);
}
}
Notez que si vous modifiez les valeurs dans le tableau d'octets après l'utilisation de l' ByteArrayWrapper
, comme une clé dans une HashMap
(etc), vous aurez des problèmes à la recherche de la clé de nouveau... vous pouvez prendre une copie des données dans l' ByteArrayWrapper
constructeur si vous le souhaitez, mais évidemment ce sera une perte de performance si vous savez que vous ne serez pas être en train de changer le contenu du tableau d'octets.
EDIT: Comme mentionné dans les commentaires, vous pouvez également utiliser ByteBuffer
(en particulier, de son ByteBuffer#wrap(byte[])
méthode). Je ne sais pas si c'est vraiment une bonne chose, compte tenu de toutes les capacités supplémentaires qu' ByteBuffer
s qui vous n'avez pas besoin, mais c'est une option.
Le problème est qu' byte[]
utilise l'identité de l'objet pour equals
et hashCode
, de sorte que
byte[] b1 = {1, 2, 3}
byte[] b2 = {1, 2, 3}
ne correspondra pas à un HashMap
. Je vois trois options:
- Emballage en
String
,, mais alors vous devez être prudent au sujet de problèmes de codage (vous avez besoin pour faire certain que l'octet -> String -> byte vous donne les mêmes octets). - Utiliser
List<Byte>
(peut être coûteux en mémoire). - Faire votre propre emballage de la classe, de l'écriture
hashCode
etequals
à utiliser le contenu du tableau d'octets.
Nous pouvons utiliser ByteBuffer pour cela (Il s’agit essentiellement du wrapper byte [] avec un comparateur)
HashMap<ByteBuffer, byte[]> kvs = new HashMap<ByteBuffer, byte[]>();
byte[] k1 = new byte[]{1,2 ,3};
byte[] k2 = new byte[]{1,2 ,3};
byte[] val = new byte[]{12,23,43,4};
kvs.put(ByteBuffer.wrap(k1), val);
System.out.println(kvs.containsKey(ByteBuffer.wrap(k2)));
imprimera
true
Vous pouvez utiliser java.math.BigInteger
. Il a un constructeur BigInteger(byte[] val)
. C'est un type de référence, il pourrait donc être utilisé comme clé pour hashtable. Et .equals()
et .hashCode()
sont définis comme pour les nombres entiers respectifs, ce qui signifie que BigInteger a une sémantique égale à égale sous forme de tableau byte [].
Je pense que les tableaux en Java n'implémentent pas nécessairement les méthodes hashCode()
et equals(Object)
intuitive. C'est-à-dire que deux tableaux d'octets identiques ne partageront pas nécessairement le même code de hachage et ne prétendront pas nécessairement être égaux. Sans ces deux traits, votre HashMap se comportera de manière inattendue.
Par conséquent, je vous recommande de ne pas utiliser byte[]
comme clés dans un HashMap.