2016-12-20 10 views
1

Я использую Hazelast Map и пытаюсь сохранить объекты против ключа, который является объектом моего пользовательского класса, то есть HMapKey. Вот фрагмент класса HMapKey.Невозможно извлечь элемент из карты Hazelcast, если использовать пользовательский объект в качестве ключа

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; 
    } 
} 

Как вы можете видеть в коде выше, я использовал метод только keyCode в равных() для сравнения двух объектов. Так что независимо от того, какое значение для переменной time. Но когда я использую этот объект в качестве ключа в карте Hazelcast и пытаюсь его восстановить, я думаю, что Hazelcast проверяет каждую переменную ключевого класса, из-за этого, даже если у меня есть одинаковое значение переменной 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), он работает нормально.

+0

Вы можете также разместить код, где вы пытаетесь получить с карты? –

+0

Обновлен мой вопрос. – Navnath

ответ

1

Это можно сделать, указав переменную time как transient. Но обратите внимание, что это приведет к столкновениям и даст случайные результаты. Ваша операция ввода будет перезаписывать предыдущее значение, даже если оно отличается от свойств.

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 
+0

Спасибо .. Это работает для меня. Но это единственный способ сделать это? Поскольку я хочу использовать эту переменную 'time' в кластере. Но это не должно быть частью проверки ключа. – Navnath

+0

Я так считаю. Вы можете изучить тему Serialization, чтобы проверить, как он преобразует ключ. Если вы хотите использовать переменную 'time', то лучше включить ее в свои реализации hashcode/equals. –

2

Прежде всего, я не знаю, что вы пытаетесь сделать, когда говорите «Я пытаюсь его восстановить».

Если вы используете ключ, как и в методе получить все работает отлично:

@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));

+0

Я обновил свой вопрос. – Navnath

+0

@tom, он не работает, даже если вы реализуете 'Comparable' –

1

Hazelcast не десериализовать ключей/значений и выполняет equals или hashCode методы, но сравнивает сериализованные объекты по их соответствующим потоковый. Если вы ищете один или несколько свойств, см. Ответ от Tom https://stackoverflow.com/a/41238649/917336

+0

Если я хочу проверить ключевой объект, используя один элемент из класса, а все, как вы упомянули, как bytestream, есть ли способ? Я постараюсь ответить Тому, но не смог добиться. – Navnath

+0

Вы не можете проверить, кроме запроса, и посмотреть, соответствует ли результат тому, что вы ожидали. – noctarius