2015-07-29 5 views
4

У меня есть программа, которая получает идентификаторы из базы данных, возвращаемой как byte[]. Я хочу использовать эти идентификаторы (байтовые массивы) в качестве ключей к карте. По умолчанию это не работает, потому что сравнивается «равенство объектов», а не «равенство содержания».Использование String (byte []) в качестве ключа для отображения

Следующее, что я пробовал, который казался, чтобы работать, создает экземпляр строки с конструктором new String(byte[]). Хотя это кажется для работы. Я знаю, что я делаю некоторые потенциально изворотливые вещи. Я не указываю кодировку, которая полагается на все системные значения по умолчанию. Я также не знаю, будут ли все байтовые последовательности иметь представление в каждой кодировке.

ли «преобразование» byte[] в String с целью делать map.put() и map.get() сейф? Есть ли крайние случаи, когда я не рассматриваю, где этот подход непреднамеренно создает столкновение (где 2 разных byte[] с разным контентом могут стать такими же String).

Примечание: Карта хранится в памяти и живет только для одного запуска приложения. Простой класс обертку я написал, чтобы сделать свою жизнь проще, если этот подход является жизнеспособным:

public class Cache { 

    Map<String, Set<String>> cache = new HashMap<String, Set<String>>(); 

    public Cache() {} 

    public void put(byte[] key, Set<String> value) { 
     cache.put(new String(key), value); 
    } 

    public Set<String> get(byte[] key) { 
     return cache.get(new String(key)); 
    } 
} 
+0

Это похоже и может быть полезным: http://stackoverflow.com/questions/16839182/can-a-java-array-be-used-as-a-hashmap-key – Chop

ответ

6

Вы, вероятно, следует использовать Biginteger. Он имеет конструктор BigInteger(byte[]) и имеет эффективную систему сравнения.

+0

Это кажется довольно простым. Я собираюсь пойти с этим, если нет вопиющей причины не делать этого. Единственное, что я могу думать о проблеме, это байт-массив с содержимым с «ведущими» нулями, но это не должно быть для меня, если это реальность. Спасибо за ответ! – Russ

2

Не могли бы вы построить простую обертку вокруг вашего массива byte[]?

Что-то похожее на:

public class CacheKey { 
    private final byte[] key; 

    public CacheKey(byte[] key) { 
     this.key = key; // You may want to do a defensive copy here 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) { 
      return true; 
     } 
     if (o == null || getClass() != o.getClass()) { 
      return false; 
     } 
     CacheKey cacheKey = (CacheKey) o; 
     return Arrays.equals(key, cacheKey.key); 
    } 

    @Override 
    public int hashCode() { 
     return key != null ? Arrays.hashCode(key) : 0; 
    } 
} 

и использовать его в качестве ключа карты? Это будет немного более легким, чем использование встроенного объекта String и делает тип ключа действительно понятным.

+0

Эй, это может сработать. Does Arrays.hashCode (prim []) создает хэш на основе содержимого массива? – Russ

+0

Этот метод hashcode и equals был фактически сгенерирован моей IDE. [Arrays.hashcode()] (http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#hashCode%28byte []% 29) гарантирует вызов [Массивы. equals()] (http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#equals%28byte [],% 20byte []% 29) между двумя массивами с одинаковыми hashcode будет оцениваться как true, поэтому он должен это сделать. –

Смежные вопросы