我有一個榛樹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文檔。 –