not sure if I should search or sort my hashmap

2020-04-19 10:56发布

问题:

Hi I have a list of people with their ages, I need to find those who are more than 30 years old, is there any possibility to search in a hashmap ? (please note that I may need to look for those in other age ranges as well so I prefer not to use two different lists for the sake of simplicity of code)

In short: My goal is to find a way to search for elements with specific values in HashMap

Sample list is

element1 40
element2 4
element3 66
element4 5

I want to find those with values more than 40 and those with values more than or equal to 66.

回答1:

I'd suggest you to use NavigableMap (Implemented as TreeSet).

This implementation is a quite fast - O(log(N)), versus O(N) if you implement index based on lists.

Edit. Example:

class PersonsAgeIndex {

    private NavigableMap<Integer, List<Person>> ageToPersons = 
                                    new TreeMap<Integer, List<Person>>();

    public void addPerson( Person p ) {
        List<Person> personsWithSameAge = this.ageToPersons.get( p.age );

        if ( personsWithSameAge == null ) {
            personsWithSameAge = new LinkedList<Person>();
            this.ageToPersons.put( p.age, personsWithSameAge );
        }

        personsWithSameAge.add( p );
    }

    public List<Person> personsWithAgeLessThan( int age ) {
        List<Person> persons = new LinkedList<Person>();

        // persons with less age
        for (List<Person> tmp : this.ageToPersons.headMap( age ).values()) {
            persons.addAll( tmp );
        }

        return persons;
    }

    public List<Person> personsWithAgeInInterval( int minAge, int maxAge ) {
        List<Person> persons = new LinkedList<Person>();

        // persons with age, which: (minAge <= age <= maxAge)
        for (List<Person> tmp : this.ageToPersons.subMap( minAge, true, maxAge, true ).values()) {
            persons.addAll( tmp );
        }

        return persons;
    }

}

class Person {
    public final int age;

    public Person(int age) {
        this.age = age;
    }
}


回答2:

Try this:

 private List<Person> getPeople(Map<?, Person> peopleMap, int filterAge) {
    List<Person> returnList = new ArrayList<Person>(peopleMap.values().size());
    for (Person p : peopleMap.values()) {
        if (p.getAge() > filterAge)
        returnList.add(p);
    }
    return returnList;
    }


回答3:

HashMapiteration order is 'not predictable' (that's to say that if you sort, and than insert keys, in a determinate order when you later try to iterate the keys the order is not the same).

Use a LinkedHashMap instead.



回答4:

Good question... unfortunately, a Map needs a very specific key. Your solution above is the only real way to do it.

Alternatively you could maintain two lists, and store those that older than 30 to the 2nd list.



回答5:

You cannot sort a HashMap, it has no order. If you want an ordered HashMap, use LinkedHashMap.



回答6:

HashMap<String,String> hmap = new HashMap<String,String>();
SortedSet<String> keys = new TreeSet<String>(hmap.keySet());

This will give you a sorted set which you could make a subset of.

keys.subSet(from,to) e.g keys.subSet(30,100)

and you will have a set with all required elemets.