2015-11-16 63 views
0

我将一个联系人列表存储为类型为“Person”的HashMap,并希望具有搜索功能,以便我可以搜索HashMap并返回名为“John”的所有人以及例如,住在美国的人。我的想法是只要创建人与环的ArrayList通过增加每个值作为例如:在多个值中搜索一个HashMap

Map<Person, Person> hm = new HashMap<Person, Person>(); 
    ArrayList<String> result = new ArrayList<String>(); 

    Enumeration num= hm.keys(); 
    String name = "John"; 
    String location = "USA"; 

    while (num.hasMoreElements()) { 
     Person person = (Person) num.nextElement(); 

     if(person.name.equals(name) && person.location.equals(location)) 
     { 
      result.add(person); 
     } 

我只是想知道这是否会工作正确的,或者如果有,我已经忽略了这样的一些更好的方法。

感谢

+1

您正在使用'Map ',但看起来您确实应该使用'Set '。您可以阅读更多:http://java67.blogspot.com.au/2013/01/difference-between-set-list-and-map-in-java.html –

回答

0

而不是使用Enumerable,我会建议你使用for语法上的按键。

for (Person person : hm.keys()) 
    { 
     // Your if statement goes here 
    } 
0

你真的想:

Set<Person> hm = new HashSet<Person>(); 
for(Person person: hm) 
{ 
    // your logic here 
} 

如果由于某种原因你还是死心塌地地在地图上,遍历这样的:

for(Map.entry<Person, Person> entry: hm.entrySet()) 
{ 
    // use entry.getKey() and entry.getValue() 
} 
0

有没有更好的结构解决方案,因为HashMap以任意的,不透明的顺序包含其密钥,任何算法都不能使用该顺序,这些算法不完全知道内部信息。因此,遍历所有元素(键)时没有干净的方法。

我也建议的文体改进已经显示为@WW。

0

除非你确实需要映射Person对象我会建议你使用一个Set,而不是Map

Set<Person> people = new HashSet<Person>(); 

的Java 8让你创建一个过滤集的一个很好的方式:

Set<Person> subset = people.stream() 
    .filter(p -> p.getName().equals(name)) 
    .filter(p -> p.getLocation().equals(location)) 
    .collect(Collectors.toSet()); 

如果你想要某些预定义的搜索条件,那么你可以创建这些方法:

class Person { 
    public static Predicate<Person> hasNameAndLocation(String name, Location location) { 
     return person -> person.name.equals(name) && person.location.equals(location); 
    } 
} 

,使您的过滤代码更漂亮,并避免使用干将:

.filter(Person.hasNameAndLocation("Fred", Country.USA)) 

如果需要非常高的性能(可能只需要数以百万计的搜索第二的项目或上千),那么解决的办法是有独立的地图,使预定的搜索速度非常快:

Map<String, Set<Person>> nameMap; 
Map<Location, Set<Person>> locationMap; 

Set<Person> subset = nameMap.get("Fred") 
    .filter(locationMap.get(Country.USA)::contains)) 
    .collect(Collectors.toSet()); 

这可能是非常快的,但让你有多个集合,以跟上你的代码要复杂得多。除非您有显着的性能要求,否则不要这样做。