如果使用自定义对象作为键,则无法从 Hazelcast 的地图中检索元素
Not able to retrieve element from Hazelcast's Map if using custom object as a key
我正在使用 Hazelast Map 并尝试根据我的自定义对象 class 即 HMapKey
的键存储对象。这是 HMapKey
class.
的片段
public class HMapKey implements Serializable{
private String keyCode;
private long time;
public HMapKey(String keyCode, long time) {
this.keyCode = keyCode;
this.time = time;
}
public String getKeyCode() {
return keyCode;
}
public void setKeyCode(String keyCode) {
this.keyCode = keyCode;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((keyCode == null) ? 0 : keyCode.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HMapKey other = (HMapKey) obj;
if (keyCode == null) {
if (other.keyCode != null)
return false;
} else if (!keyCode.equals(other.keyCode))
return false;
return true;
}
}
正如您在上面的代码中看到的,我在 equals() 方法中只使用了 keyCode
来比较两个对象。因此,无论 time
变量的值是多少。
但是当我在 Hazelcast 的 Map 中使用这个对象作为键并尝试检索它时,我认为 Hazelcast 检查键 class 的每个变量,因此,即使我有相同的 keyCode
变量值和不同的 time
变量,Hazelcast 以 NULL
返回我。是否有任何配置告诉 Hazelcast 不要进行所有变量检查并仅使用现有的 equals()
方法?
这是我尝试从地图检索数据的代码
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
private static ConcurrentMap<HMapKey, String> testMap = instance.getMap("TEST_MAP");
testMap.put(new HMapKey("code1",123), "This is Code 1");
System.out.println(testMap.get(new HMapKey("code1",0)));
意思是,在插入时,我创建了像 new HMapKey("code1",123)
这样的关键对象,但在检索它时,我正在创建新对象 new HMapKey("code1",0)
,这将我作为空值返回。而如果我尝试 new HMapKey("code1",123)
它工作正常。
首先,我不知道你说"I try to retrieve it"时想做什么。
如果您像在 get 方法中那样使用密钥,一切正常:
@Test
public void test() {
HazelcastInstance hz = createHazelcastInstance();
IMap<HMapKey, Integer> map = hz.getMap("aaa");
HMapKey key = new HMapKey();
key.keyCode = "code1";
key.time = 123;
HMapKey key2 = new HMapKey();
key2.keyCode = "code2";
key2.time = 246;
map.put(key, 1);
map.put(key2, 2);
int value = map.get(key);
assertEquals(value, 1);
}
如果要根据整个键值检索值,HMapKey 需要实现 Comparable
。
那么你可以这样查询:
map.values(Predicates.equal("__key", yourHKMapKeyInstance));
Hazelcast 不会反序列化键/值并执行 equals
或 hashCode
方法,而是通过相应的字节流比较序列化对象。如果您正在搜索一处或多处房产,请参阅 Tom
的回答
您可以通过将变量 time
声明为 transient
来实现。但请注意,这会导致碰撞并给出随机结果。您的 put 操作将覆盖以前的值,即使它的属性不同。
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
IMap<HMapKey, String> testMap = instance.getMap("TEST_MAP");
testMap.put(new HMapKey("code1",123), "This is Code 1");
System.out.println("HMapKey with time=0: " + testMap.get(new HMapKey("code1",0)));
System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
testMap.put(new HMapKey("code1",456), "This is Code 2");
System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
输出将是:
HMapKey with time=0: This is Code 1
HMapKey with time=123: This is Code 1
HMapKey with time=123: This is Code 2
我正在使用 Hazelast Map 并尝试根据我的自定义对象 class 即 HMapKey
的键存储对象。这是 HMapKey
class.
public class HMapKey implements Serializable{
private String keyCode;
private long time;
public HMapKey(String keyCode, long time) {
this.keyCode = keyCode;
this.time = time;
}
public String getKeyCode() {
return keyCode;
}
public void setKeyCode(String keyCode) {
this.keyCode = keyCode;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((keyCode == null) ? 0 : keyCode.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HMapKey other = (HMapKey) obj;
if (keyCode == null) {
if (other.keyCode != null)
return false;
} else if (!keyCode.equals(other.keyCode))
return false;
return true;
}
}
正如您在上面的代码中看到的,我在 equals() 方法中只使用了 keyCode
来比较两个对象。因此,无论 time
变量的值是多少。
但是当我在 Hazelcast 的 Map 中使用这个对象作为键并尝试检索它时,我认为 Hazelcast 检查键 class 的每个变量,因此,即使我有相同的 keyCode
变量值和不同的 time
变量,Hazelcast 以 NULL
返回我。是否有任何配置告诉 Hazelcast 不要进行所有变量检查并仅使用现有的 equals()
方法?
这是我尝试从地图检索数据的代码
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
private static ConcurrentMap<HMapKey, String> testMap = instance.getMap("TEST_MAP");
testMap.put(new HMapKey("code1",123), "This is Code 1");
System.out.println(testMap.get(new HMapKey("code1",0)));
意思是,在插入时,我创建了像 new HMapKey("code1",123)
这样的关键对象,但在检索它时,我正在创建新对象 new HMapKey("code1",0)
,这将我作为空值返回。而如果我尝试 new HMapKey("code1",123)
它工作正常。
首先,我不知道你说"I try to retrieve it"时想做什么。
如果您像在 get 方法中那样使用密钥,一切正常:
@Test
public void test() {
HazelcastInstance hz = createHazelcastInstance();
IMap<HMapKey, Integer> map = hz.getMap("aaa");
HMapKey key = new HMapKey();
key.keyCode = "code1";
key.time = 123;
HMapKey key2 = new HMapKey();
key2.keyCode = "code2";
key2.time = 246;
map.put(key, 1);
map.put(key2, 2);
int value = map.get(key);
assertEquals(value, 1);
}
如果要根据整个键值检索值,HMapKey 需要实现 Comparable
。
那么你可以这样查询:
map.values(Predicates.equal("__key", yourHKMapKeyInstance));
Hazelcast 不会反序列化键/值并执行 equals
或 hashCode
方法,而是通过相应的字节流比较序列化对象。如果您正在搜索一处或多处房产,请参阅 Tom
您可以通过将变量 time
声明为 transient
来实现。但请注意,这会导致碰撞并给出随机结果。您的 put 操作将覆盖以前的值,即使它的属性不同。
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
IMap<HMapKey, String> testMap = instance.getMap("TEST_MAP");
testMap.put(new HMapKey("code1",123), "This is Code 1");
System.out.println("HMapKey with time=0: " + testMap.get(new HMapKey("code1",0)));
System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
testMap.put(new HMapKey("code1",456), "This is Code 2");
System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
输出将是:
HMapKey with time=0: This is Code 1
HMapKey with time=123: This is Code 1
HMapKey with time=123: This is Code 2