我有一个榛树Ilist,学生类包含5个属性,如(ID,姓名,地址,号码,学校)。现在列表中有10K条记录,我怎么能找到学生除了for循环之外,我的名字是tony,编号是001。我知道它是否是Imap我可以使用谓词来过滤,但它是一个列表,我没有找到Ilist的谓词。任何帮助,都非常感谢。快速在榛树列表中找到一个条目
回答
不幸的是,没有办法用某种谓词或其他魔法来做到这一点。你必须做一个循环。但是,为了加快速度,您应该在包含列表的成员上运行此搜索。分区由列表的名称来定义。你基本上可以自己写一个小的“查询引擎”来在列表顶部使用Hazelcast谓词。
我创建了一个基本的例子,你可以最有可能优化它。
一个简单的学生类:
public class Student implements Serializable {
private long id;
private String name;
private String address;
private String number;
private String school;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
public String getNumber() { return number; }
public void setNumber(String number) { this.number = number; }
public String getSchool() { return school; }
public void setSchool(String school) { this.school = school; }
@Override
public String toString() {
return "Student{" + "id=" + id
+ ", name='" + name + '\''
+ ", address='" + address + '\''
+ ", number='" + number + '\''
+ ", school='" + school + '\'' + '}';
}
}
搜索执行人:
public class StudentSearch {
private final IExecutorService executorService;
public StudentSearch(HazelcastInstance hazelcastInstance) {
this.executorService =
hazelcastInstance.getExecutorService("student_search");
}
public Student findFirstByNameAndNumber(String listName,
String name,
String number)
throws Exception {
Predicate namePredicate = Predicates.equal("name", name);
Predicate numberPredicate = Predicates.equal("number", number);
Predicate predicate = Predicates.and(namePredicate, numberPredicate);
StudentSearchTask task = new StudentSearchTask(listName, predicate);
Future<Student> future = executorService.submitToKeyOwner(task, listName);
return future.get();
}
private static class StudentSearchTask
implements Callable<Student>,
DataSerializable,
HazelcastInstanceAware {
private HazelcastInstance hazelcastInstance;
private String listName;
private Predicate predicate;
public StudentSearchTask() {
}
public StudentSearchTask(String listName, Predicate predicate) {
this.listName = listName;
this.predicate = predicate;
}
@Override
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
@Override
public Student call() throws Exception {
IList<Student> list = hazelcastInstance.getList(listName);
Optional<Map.Entry<String, Student>> first =
list.stream()
.map(this::makeMapEntry)
.filter(predicate::apply)
.findFirst();
return first.orElse(makeMapEntry(null)).getValue();
}
@Override
public void writeData(ObjectDataOutput out) throws IOException {
out.writeUTF(listName);
out.writeObject(predicate);
}
@Override
public void readData(ObjectDataInput in) throws IOException {
listName = in.readUTF();
predicate = in.readObject();
}
private Map.Entry<String, Student> makeMapEntry(Student student) {
return new QueryEntry(listName, student);
}
}
// Used to query the list entries
private static class QueryEntry
implements Map.Entry<String, Student>,
Extractable {
private final String key;
private final Student value;
private QueryEntry(String key, Student value) {
this.key = key;
this.value = value;
}
@Override
public Object getAttributeValue(String attributeName)
throws QueryException {
if ("number".equals(attributeName)) {
return value.getNumber();
} else if ("name".equals(attributeName)) {
return value.getName();
}
return null;
}
@Override
public AttributeType getAttributeType(String attributeName)
throws QueryException {
return AttributeType.STRING;
}
@Override
public String getKey() {
return key;
}
@Override
public Student getValue() {
return value;
}
@Override
public Student setValue(Student value) {
throw new UnsupportedOperationException();
}
}
}
最后如何运行这段代码:
List<Student> students = hz.getList(listName);
addStudents(students);
StudentSearch search = new StudentSearch(hz);
Student result = search
.findFirstByNameAndNumber(listName, "Tony", "001");
System.out.println(result);
我希望这有助于一点:)
由于您需要查询id + name(因此id不是唯一的?),我无法获得对象中的id是什么。如果您知道需要查询它们,为什么将它们存储在Set中(请提供更多信息)。
正如您所指出的,Set中没有谓词。恕我直言,这是因为没有与密钥关联的条目不能被索引。没有可能性来索引索引(或者在leas范围内扫描关键字),谓词的概念就会崩溃,因为任何查询都会遍历整个集合。据我所知,你没有太多的选择:
如果你使用set必须有唯一的条目,不要!
在这种情况下,将其移动到地图上,使用任何人的密钥,例如您的对象id。如果可能有id,重复,则可以制作更复杂的关键字,例如id + name,甚至可以散列整个对象。一旦你必须把一个新的对象作为关键字,并检查它是否已经存在,如果是这样的自定义逻辑回退。地图会给你所有你想要的索引和谓词。
从另一方面,如果由于某种原因不在你的控制之下,必须使用一套......那么你可以做它在很多方面,但我会建议如下:
听任何修改设置(或者,如果是静态或稠度不关心定期扫描设置
构建您的自定义索引
如何构建索引:
它确实取决于您想要的性能,可以接受的内存影响以及不同的查询可能会如何。(假设你只有查询总是相同的,例如“name等于”)。
MultiMap<String, String> index
// index.put(name, key)
可通过添加,每个集合修改删除条目,使用您的多重映射的object.name如SET键,实际密钥,这在多重映射价值结构索引。当你搜索一个给名你只需做如下(伪伪代码)
MultiMap<String, String> index;
Map<String, your_object_class> your_set;
function getByName(String name)
{
List<String> name_key_set index.get(name);
List<your_object_class> out;
for(String key : name_key_set)
out.add(index.get(key));
return out;
}
IMO没有什么可以调用的一个集查询(指查询作为一个聪明的方法来检索数据而不是蛮力迭代),因为任何这样的系统将要求key =>值条目。
随着进一步的信息,我们可以帮助您更好地:)
- 1. 在C#中快速查找子列表
- 2. 快速找到Linux上的一个目录中的文件数
- 3. Eclipse热键快速找到一个包
- 4. 火狐条快速找到API文档
- 5. 哪一个在散列表或排序列表中找到一个项目更快?
- 6. 快速shell找到
- 7. 如何在大整数列表中快速找到列表元素的第一个倍数?
- 8. Rails在范围表中找到一个特定的条目
- 9. Android:快速查找联系人列表
- 10. 根据另一个表上的条件在一个MySQL表中查找条目
- 11. 快速筛选列表框项目wpf?
- 12. 寻找一个快速概述的线条渲染算法
- 13. 快速找到一个数字的下一个倍数
- 14. 锁定榛树群集中的密钥
- 15. 当列表中有一个条目时,计算列表中的条目数
- 16. 在列表中找到一个字母
- 17. 找到一个树形结构表
- 18. 在Microsoft CRM中快速创建表单中添加一个快速字段
- 19. SWT的“快速查找”表
- 20. Python:在列表中找到一个项目
- 21. PseudoCode for Python:在列表中找到一个项目
- 22. 查找重复项并返回列表(类)在一个快速的方式
- 23. 帮助在C#中找到快速排列/组合算法
- 24. 快速:找不到模块?
- 25. 快速查找列表的方法包含两个特定项目?
- 26. JPA找到最后一个条目
- 27. INDEX/MATCH仅在具有多个条目的列中找到第一个值
- 28. 将一个文件中的单列条目匹配到第二个文件中的列条目,该列条目由一个列表组成
- 29. 根据项目条件在两个列表中查找索引
- 30. 在Python中输入一个列表中的每个条目3
很好的例子@noctarius。这应该转到SO文档。 –