问题
I am using Hazelast Map and trying to store Objects against key which is object of my custom class i.e. HMapKey
. Here is snippet of 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;
}
}
As you can see in above code, I have used only keyCode
in equals() method to compare two objects. So no matter what value is there for time
variable.
But when I use this object as key in Hazelcast's Map, and try to retrieve it, I think Hazelcast checking each and every variable of key class, because of this, even if I have same keyCode
variable value and different time
variable, Hazelcast returning me as NULL
. Is there any configuration to tell Hazelcast not to go for all variable checking and use existing equals()
method only?
Here is code how I am trying to retrieve data from map
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)));
Means, while insertion, I have created key object like new HMapKey("code1",123)
but while retrieving it, I am creating new object as new HMapKey("code1",0)
and this is returning me as null value. Whereas if I try with new HMapKey("code1",123)
it's working fine.
回答1:
You can achieve that by declaring variable time
as transient
. But note that it will lead to collisions and give random results. Your put operation would overwrite the previous value even though it's properties are different.
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)));
Output would be:
HMapKey with time=0: This is Code 1
HMapKey with time=123: This is Code 1
HMapKey with time=123: This is Code 2
回答2:
First of all, I don't know what you're trying to do when you say "I try to retrieve it".
If you use your key as in the get method everything works fine:
@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);
}
If you want to retrieve a value basing on the whole key value the HMapKey needs to implement Comparable
.
Then you can query like this:
map.values(Predicates.equal("__key", yourHKMapKeyInstance));
回答3:
Hazelcast does not deserialize the keys / values and executes equals
or hashCode
methods but compares the serialized objects by their corresponding bytestream. If you're searching for one or more properties, please see the answer from Tom https://stackoverflow.com/a/41238649/917336
来源:https://stackoverflow.com/questions/41238403/not-able-to-retrieve-element-from-hazelcasts-map-if-using-custom-object-as-a-ke