2015-03-23 3 views
0

У меня есть базовый код Hashmap, который по какой-то причине не работает.get in Hashmap возвращает null

ConcurrentHashMap<Bitmap, byte[]> pixels = new ConcurrentHashMap<Bitmap, byte[]>(); 

это ключ растровый и значение являются его байты, которые я получаю, используя этот код:

public byte[] getPixels(Bitmap bmp) { 
    int bytes = bmp.getRowBytes() * bmp.getHeight(); 
buffer = ByteBuffer.allocateDirect(bytes); 
    bmp.copyPixelsToBuffer(buffer); 
    buffer.clear(); 
    return buffer.array(); 
} 

В HashMap для всех растровых изображений я я поставил:

pixels.put(bitmap1, getPixels(b)); 

И когда я хочу получить значение (байты) назад, я делаю:

byte[] pixelData = pixels.get(bitmap1); 

и по какой-то нечетной причине его всегда null !, почему? Я пробовал разные растровые изображения, все они возвращают null, и это то же растровое изображение.

+0

Erm ... Вы не можете вызвать '.array()' в прямом распределенном 'ByteBuffer'. Там что-то происходит. – fge

+0

@fge Я могу, код работает и работал до того, как я использовал hashmap. Это часть этого решения: http: // stackoverflow.com/a/29061657/4024143 – SpoocyCrep

ответ

1

Это должен быть тот же экземпляр Bitmap. Если вы создадите другой экземпляр одного растрового изображения, это будет не тот же объект.

Например:

Bitmap b1 = BitmapFactory.decodeFile("mybitmap.png"); 
ConcurrentHashMap<Bitmap, byte[]> pixels = new ConcurrentHashMap<Bitmap, byte[]>(); 
pixels.add(b1); 
[...] 
Bitmap b2 = BitmapFactory.decodeFile("mybitmap.png"); 
byte[] barray1 = pixels.get(b1); 
byte[] barray2 = pixels.get(b2); 

barray1 не является нулевым

barray2 является нулевым

+0

, и если я скажу b2 = b1; и дать b2, он вернет null? потому что, как это в моем коде, у меня нет новых декодированных файлов, я использую те же растровые изображения. – SpoocyCrep

+0

@SpoocyCrep, если битмап не «воссоздан» (новый экземпляр или coy из BitmapFactory или Bitmap), он должен работать – LaurentY

+0

Вы правы, я обнаружил свою ошибку - я исказил растровое изображение после вставки его в hashmap, не заметив , Я добавил его после масштабирования, и он работает. – SpoocyCrep

1

Первые вещи: Javadoc из андроида Bitmap не дает никаких гарантий, что она поддерживает equals() и hashCode(), если у них есть то же самое, что означает, что если они этого не сделают, вы ввернуты.

Вторые: the javadoc of ByteBuffer.allocateDirect() гласит:

ли она или нет имеет массив подкладочный не определенно.

Поэтому -> не использовать, что использовать ByteBuffer.allocate() вместо который гарантированно иметь массив подкладочный.

Но я предполагаю, что проблема связана с первым пунктом.

+0

Хорошо, я изменил его, чтобы выделить, но проблема остается прежней. Я не говорю два разных растровых изображения с одним и тем же контентом, растровые изображения все указывают на одно и то же растровое изображение, при создании я загружаю некоторые растровые изображения и отправляю их в классы. Я не изменяю растровое изображение, так что это действительно странно .. – SpoocyCrep

1

Всякий раз, когда вы используете HashMap и вы лечите определенный тип объекта в качестве ключа , необходимо рассмотреть вопрос о целесообразности метода этого объекта equals() разработана должным образом для проверки пользовательского равенства. В большинстве случаев это не так, поэтому вам нужно повторно реализовать метод equals().

Превалирующая логика на Java заключается в том, что когда вы переопределяете equals(), вы также должны переопределить метод hashCode(). (См this post)

Другими словами, вам нужно вывести класс CustomBitmap из Bitmap и добавить новые реализации equals() и hashCode() к новому классу. Затем он может быть успешно использован в качестве ключа в HashMap.

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