进入 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
.
中的密钥
我有一个基本的 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
.