我有一个以类为键的IMap
。该键具有两个属性:
static class MapKey implements Serializable{
String uid;
String service;
public MapKey() {
}
public MapKey(String uid, String service) {
this.uid = uid;
this.service = service;
}
public String getUid() {
return uid;
}
...
}
我仅用两个简单值初始化地图:
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
final IMap<MapKey, String> map = hz.getMap("testmap");
map.addIndex("__key#uid", false);
map.put(new MapKey("uid1","service1"),"value1");
map.put(new MapKey("uid1","service2"),"value2");
然后,我用ands建立谓词:
static Predicate<MapKey, String> buildPredicate(MapKey key){
final EntryObject entryObject = new PredicateBuilder().getEntryObject().key();
final List<Predicate<MapKey, String>> predicateList = new ArrayList<>();
predicateList.add(entryObject.get("uid").equal(key.getUid()));
predicateList.add(entryObject.get("service").equal(key.getService()));
final com.hazelcast.query.Predicate predicate = Predicates.and(predicateList.toArray(new Predicate[predicateList.size()]));
return predicate;
}
当我使用此谓词时,它返回的键仅由uid过滤,这意味着Collection值的大小为2,而不是预期的大小。
Predicate<MapKey, String> predicate = buildPredicate(new MapKey("uid1","service1"));
Collection<MapKey> values = map.keySet(predicate);
有人可以向我解释这种行为吗?我缺少什么?
问题是,如果它是一个不可变的对象,则对entryObject
进行操作,但是它不是不可变的。它实际上是一个构建器,并且操作entryObject.get("uid").equal(key.getUid())
更改其状态并记录谓词条件。因此,如果对两个完全相等的谓词执行Predicates.and()
,则会产生效果。
尝试以下操作,它将完成您尝试实现的目标。
static Predicate<MapKey, String> buildPredicate(MapKey key){
final List<Predicate<MapKey, String>> predicateList = new ArrayList<>();
predicateList.add(new PredicateBuilder().getEntryObject().key().get("uid").equal(key.getUid()));
predicateList.add(new PredicateBuilder().getEntryObject().key().get("service").equal(key.getService()));
final com.hazelcast.query.Predicate predicate = Predicates.and(predicateList.toArray(new Predicate[predicateList.size()]));
return predicate;
}