put函数工作正常但get函数没有。显然我不知道这个伎俩。
>> X = [ 1, 2, 3];
>> M = java.util.HashMap;
>> M.put(X,1);
>> M.get([1,2,3])
ans = []
我搜索并阅读了很多帖子,但找不到解决此问题的方法。 如果有人能让我知道这个伎俩,那就太好了。
答案 0 :(得分:6)
我认为问题在于Java原始数组不能为您提供正确的equals()和hashCode()。它们使用标准的Object方法,这些方法按对象标识而不是包含的值进行比较。当使用非标量数组作为HashMap中的键时,Matlab会将它们转换为double [],但它们将是不同的Java对象,因此它们会得到这种行为。
如果将数组值包装在为equals()和hashCode()提供by-value行为的Java对象中,然后再将它们用作键,则可以使用它。幸运的是,java.util.Arrays为原始数组提供了按值实现。我们只需要在一个提供HashMap所期望的接口的包装类中打它们。
package test;
import java.util.Arrays;
/**
* A double[] that with by-value semantics for equals() and hashCode() so you
* can use it in HashMaps.
* In a non-toy class, you'd probably use switch statements to support arrays
* of any primitive type. In a language with real generics, you'd just template
* this.
*/
public class EqualByValueDoubleArray {
private double[] x;
public EqualByValueDoubleArray(double[] x) { this.x = x; }
public double[] getArray() { return x; };
public boolean equals(Object obj) {
if (obj instanceof EqualByValueDoubleArray) {
return Arrays.equals(this.x, ((EqualByValueDoubleArray)obj).x);
} else {
return false;
}
}
public int hashCode() { return Arrays.hashCode(x); }
}
现在你可以将它们包装起来并将它们用作Matlab中的键。
function scratch_array_keyed_hashmap
import test.EqualByValueDoubleArray;
map = java.util.HashMap;
a = [1 2 3 4 5]';
key = EqualByValueDoubleArray(a);
map.put(key, 'my value');
% Separate key so we know it's comparing by value, not Java object identity
key2 = EqualByValueDoubleArray(a);
gotBack = map.get(key2)
这适用于R2008b。
>> scratch_array_keyed_hashmap
gotBack =
my value
为了便于使用,您可以创建一个HashMap子类,该子类检查其输入键的类型,并在此按值包装器中自动包装原始数组。
答案 1 :(得分:1)
我认为你不能使用数字向量或矩阵作为Java hashmap中的键。相反,您必须将向量或矩阵转换为单个唯一键,例如向量或矩阵中值的唯一字符串表示。有几种方法可以做到这一点:
对于整数数组,可以使用CHAR函数将整数转换为等效的ASCII表示形式,从而创建字符串。这仅适用于0到65535之间的整数值,因为此范围之外的任何内容都可能具有未定义的行为。这是一个例子:
X = [1 2 3; 4 5 6]; % X is a 2-by-3 matrix
keyValue = char(X(:)'); % Reshape X to a row vector and convert to ASCII
如果整数值太大而无法使用CHAR,则可以改为使用INT2STR:
keyValue = int2str(X(:)');
对于浮点数组,您可以使用NUM2STR函数创建连接在一起的每个数组元素的格式化字符串表示形式。这是一个例子:
X = rand(2,3)*9999; % X is a 2-by-3 matrix of random double values
keyValue = num2str(X(:)','%10.5f');
为了确保密钥的唯一性(通过避免浮点值的舍入),您可以使用DEC2BIN将double值转换为完整的64位二进制表示。但是,这可能会导致巨大的字符键:
keyValue = reshape(dec2bin(X(:),64)',1,[]);
这些选项的一个缺点是您的密钥可能最终成为相当长的字符串。我不确定密钥中的字符数是否有上限,或者在使用密钥长字符串时是否存在性能损失。
答案 2 :(得分:0)
Matlab结构提供了非常快速的字母数字键查找(嗯,[a-zA-Z] [a-zA-Z_0-9] *匹配);没错,如果你试图从数字哈希,我会建议使用数组加倍的稀疏数组;让arrayvalue指向您想要查找的任何内容的索引。 HTH
答案 3 :(得分:-1)
如果您正在使用更新版本的MATLAB(我认为是2008b或更高版本),那么MATLAB有自己的地图类,适用于某些类型的键。请参阅文档:containers.Map