我的最后一次尝试得到了很好的解释,所以很有希望得到更清晰的解释。
我有一个具有以下数据结构的Collection。
LinkedHashMap<String, String> currentHashMap = new LinkedHashMap<String, String>();
currentHashMap.put("id","12345");
currentHashMap.put("firstName","John");
currentHashMap.put("lastName","Doe");
haystack.add(currentHashMap);
*重复约250,000个条目
我需要搜索每个列表条目中的HashMaps,检查密钥是否存在,以及它是否具有相应的值。如果是,我想返回该特定hashmap中的所有值
这是我目前正在使用的代码。
private TreeSet<String> searchWithinCollection(List<LinkedHashMap<String, String>> haystack, String needle, String needleKey) {
TreeSet<String> returnValueSet = new TreeSet<>();
for (LinkedHashMap<String, String> mappedData : haystack) {
System.out.println(mappedData.values());
for (Entry<String, String> specificData : mappedData.entrySet()) {
if (needleKey.equals(specificData.getKey()) && needle.equals(specificData.getValue())) {
//where I want to collect the values within the current hashmap, as it's satisfied the search criteria
//the current code would only return the current key/balue pair, even if all values were collected outside the for loop. Instead, I'd want to collect "12345", "John", "Doe" if needleKey = id and needle = 12345.
}
}
}
return returnValueSet;
}
我想要的是,如果当前集合中的某个键等于&#34; id&#34;,并且它的值等于&#34; 12345&#34;,那么我可以返回所有该特定集合中的值(并使用上面的示例,将是&#34; 12345&#34;,&#34; John&#34;,&#34; Doe&#34;)。 我能做的最好的就是返回第一个键/值,这显然不是很有用。尝试捕获第二个for循环外的mappedData中的所有值都没有带来任何结果(无论是创建Collection的新实例,克隆还是有什么东西。)。我还发现没有什么可以手动推进每个循环中的指针来手动捕获Collection中的所有值。
编辑:如果有帮助,那么有一个System.out.println(mappedData.values());我可以得到我期望的值,但如果在if语句中访问values(),则只返回示例中的id。
答案 0 :(得分:4)
您不应该遍历hashmap中的所有条目(当前,代码中的循环for (Entry<String, String> specificData : mappedData.entrySet())
。这会破坏维护hashmap的目的。
相反,内循环应该变为
String potentialNeedle = mappedData.get(needleKey);
if (needle.equals(potentialNeedle))
returnValueSet.addAll(mappedData.values());
答案 1 :(得分:2)
您正在使用地图,就好像它是一个条目列表,这完全违背了地图的目的:快速访问给定密钥的值:
for (Map<String, String> mappedData : haystack) {
String value = mappedData.get(needleKey);
if (needle.equals(value)) {
returnValueSet.addAll(mappedData.values());
}
}
答案 2 :(得分:1)
也许您应该重新设计帐户以提高效果。为您要搜索的每个字段创建一个地图可能很聪明。而不是你的干草堆创建你的数据结构:
public class PersonDataManager {
private final Map<Integer, Map<String, String>> baseData;
private final Map<String, List<Integer>> firstNameLookupMap;
private final Map<String, List<Integer>> lastNameLookupMap;
public PersonDataManager(){
this.baseData = new HashMap<>();
this.firstNameLookupMap = new HashMap<>();
this.lastNameLookupMap = new HashMap<>();
}
public void addPerson(Integer id, String firstName, String lastName){
//try to find existing person to update:
Map<String, String> personMap = baseData.get(id);
if(personMap == null){
personMap = new HashMap<>();
baseData.put(id, personMap);
}
personMap.put("firstName", firstName);
personMap.put("lastName", lastName);
//add to lookup-maps
addLookupName(firstNameLookupMap, id, firstName);
addLookupName(lastNameLookupMap, id, lastName);
}
private static void addLookupName(Map<String, List<Integer>> nameMap, Integer id, String name){
//get existing list of the name:
List<Integer> idList = nameMap.get(name);
if(idList == null){
idList = new ArrayList<>();
}
if(!idList.contains(id)){
idList.add(id);
}
}
private List<Map<String, String>> searchByName(Map<String, List<Integer>> nameMap, String name){
List<Integer> matchingIds = nameMap.get(name);
List<Map<String, String>> result = new ArrayList<>();
if(matchingIds != null){
for(Integer id : matchingIds){
result.add(searchById(id));
}
}
return result;
}
public Map<String, String> searchById(Integer id){
return baseData.get(id);
}
public List<Map<String, String>> searchByFirstName(String name){
return searchByName(firstNameLookupMap, name);
}
public List<Map<String, String>> searchByLastName(String name){
return searchByName(lastNameLookupMap, name);
}
}
通过这种方式,您可以轻松获取使用其ID的人的哈希映射。如果您需要使用名字或姓氏进行搜索,则可以使用其他地图来获取匹配的人员ID。希望这有帮助
编辑:刚刚实现了一个完全符合我认为你可能需要的课程。玩得开心;)