进入 Hashmap returns null

get in Hashmap returns null

我有一个基本的 Hashmap 代码,由于某种原因无法使用。

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();
}

在我拥有的所有位图的散列表中:

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

当我想取回值(字节)时,我会这样做:

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

并且由于某些奇怪的原因它总是空的!,为什么?我尝试了不同的位图,它们都是 return null,而且它是相同的位图..

必须是同一个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 为空

首先:Android 的 Bitmap 的 javadoc 不保证它支持 equals()hashCode() 如果它们具有相同的内容,这意味着如果他们不这样做,那你就完蛋了。

第二:the javadoc of ByteBuffer.allocateDirect() 指出:

Whether or not it has a backing array is unspecified.

因此 --> 不要使用它,而是使用 ByteBuffer.allocate()保证 有一个后备数组。

但我想问题出在第一点。

每当你使用一个HashMap并且你将某种类型的对象当作一个时,你需要考虑那个对象的equals()方法是否是为自定义相等检查正确设计。大多数情况下不是,所以你需要重新实现equals()方法。

Java 中的普遍逻辑是,当您覆盖 equals() 时,您还必须覆盖 hashCode() 方法。 (参见 this post

换句话说,你需要从Bitmap派生一个class CustomBitmap,并在新的equals()hashCode()中添加新的实现=30=]。然后它可以成功用作HashMap.

中的密钥