【问题标题】:Searching a HashMap for multiple values在 HashMap 中搜索多个值
【发布时间】:2015-11-16 22:57:05
【问题描述】:

我将联系人列表存储为“Person”类型的 HashMap,并希望有一个搜索功能,我可以搜索 HashMap,然后返回所有名字为“John”且居住在美国的人,例如。我的想法是创建一个 Person 的 ArrayList 并循环添加每个值:

  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);
         }

我只是想知道这是否可以正常工作,或者是否有一些我忽略的更好的方法。

谢谢

【问题讨论】:

标签: java loops search arraylist hashmap


【解决方案1】:

除非您确实需要映射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);
    }
}

这使您的过滤代码更好,并避免使用 getter:

.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());

这可能非常快,但会使您的代码更加复杂,因为您有多个集合要保持最新状态。除非您有重要的性能要求,否则不要这样做。

【讨论】:

    【解决方案2】:

    建议您在键上使用for 语法,而不是使用Enumerable

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

    【讨论】:

      【解决方案3】:

      你真的想要:

      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()
      }
      

      【讨论】:

        【解决方案4】:

        没有更好的结构解决方案,因为 HashMap 以任意、不透明的顺序包含其键,任何不完全了解内部结构的算法都无法使用该顺序。因此,没有干净的方法可以遍历所有元素(键)。

        我还建议的风格改进已经显示为 @WW。

        【讨论】:

          【解决方案5】:
              Map<String, Integer> myMap = new TreeMap<String, Integer>();
              List<Entry<String, Integer>> listOfEntries = new ArrayList<Entry<String, Integer>>(myMap.entrySet());
          
               for(int i=0;i<listOfEntries.size();i++){
          //listOfEntries.get(0).getValue(), put your condition for comparison   
                      if(listOfEntries.get(0).getValue()==listOfEntries.get(i).getValue()){
                                  System.out.println(listOfEntries.get(i));
                              }
                          }
          

          【讨论】:

            猜你喜欢
            • 2015-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-17
            • 2014-03-05
            相关资源
            最近更新 更多