如果使用自定义对象作为键,则无法从Hazelcast的Map中检索元素

时间:2016-12-20 09:05:40

标签: hazelcast hazelcast-imap

我正在使用Hazelast Map并尝试将对象存储到我的自定义类的对象key HMapKey。这是HMapKey类的摘录。

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会检查关键类的每个变量,因此,即使我有相同的keyCode变量值和不同的{{ 1}}变量,Hazelcast将我作为time返回。是否有任何配置告诉Hazelcast不要进行所有变量检查并仅使用现有的NULL方法?

以下是我试图从地图

中检索数据的代码
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),这将返回null值。然而,如果我尝试new HMapKey("code1",0),它的工作正常。

3 个答案:

答案 0 :(得分:2)

首先,当你说“我试图检索它”时,我不知道你要做什么。

如果你在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));

答案 1 :(得分:1)

Hazelcast不会对键/值进行反序列化并执行equalshashCode方法,但会将序列化对象与其对应的字节流进行比较。如果您要搜索一个或多个媒体资源,请参阅Tom https://stackoverflow.com/a/41238649/917336

的答案

答案 2 :(得分:1)

您可以通过将变量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