簡體   English   中英

在HashMap中搜索多個值

[英]Searching a HashMap for multiple values

我將聯系人列表存儲為類型為“ 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);
         }

我只是想知道這是否行得通,或者是否有更好的方法被我忽略了。

謝謝

建議您不要在鍵上使用for語法,而不要使用Enumerable

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

你真的想要:

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

沒有任何一種結構上更好的解決方案,因為HashMap以任意,不透明的順序包含其鍵,無法完全不了解內部原理的任何算法都無法使用它。 因此,沒有遍歷所有元素(鍵)的干凈方法。

我還要建議的樣式改進已顯示為@WW。

除非您確實需要映射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());

這可能非常快,但是由於您有多個集合要保持最新狀態,因此會使代碼變得更加復雜。 除非您對性能有重大要求,否則請不要這樣做。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM