How to sort a HashMap in Java

427,098

Solution 1

Do you have to use a HashMap? If you only need the Map Interface use a TreeMap


If you want to sort by comparing values in the HashMap. You have to write code to do this, if you want to do it once you can sort the values of your HashMap:

Map<String, Person> people = new HashMap<>();
Person jim = new Person("Jim", 25);
Person scott = new Person("Scott", 28);
Person anna = new Person("Anna", 23);

people.put(jim.getName(), jim);
people.put(scott.getName(), scott);
people.put(anna.getName(), anna);

// not yet sorted
List<Person> peopleByAge = new ArrayList<>(people.values());

Collections.sort(peopleByAge, Comparator.comparing(Person::getAge));

for (Person p : peopleByAge) {
    System.out.println(p.getName() + "\t" + p.getAge());
}

If you want to access this sorted list often, then you could insert your elements into a HashMap<TreeSet<Person>>, though the semantics of sets and lists are a bit different.

Solution 2

Sorted List by hasmap keys:

SortedSet<String> keys = new TreeSet<String>(myHashMap.keySet());

Sorted List by hashmap values:

SortedSet<String> values = new TreeSet<String>(myHashMap.values());

In case of duplicated map values:

List<String> mapValues = new ArrayList<String>(myHashMap.values());
Collections.sort(mapValues);

Good Luck!

Solution 3

Seems like you might want a treemap.

http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html

You can pass in a custom comparator to it if that applies.

Solution 4

In Java 8:

Comparator<Entry<String, Item>> valueComparator = 
    (e1, e2) -> e1.getValue().getField().compareTo(e2.getValue().getField());

Map<String, Item> sortedMap = 
    unsortedMap.entrySet().stream().
    sorted(valueComparator).
    collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                             (e1, e2) -> e1, LinkedHashMap::new));

Using Guava:

Map<String, Item> map = ...;
Function<Item, Integer> getField = new Function<Item, Integer>() {
    public Integer apply(Item item) {
        return item.getField(); // the field to sort on
    }
};
comparatorFunction = Functions.compose(getField, Functions.forMap(map));
comparator = Ordering.natural().onResultOf(comparatorFunction);
Map<String, Item> sortedMap = ImmutableSortedMap.copyOf(map, comparator);

Solution 5

Custom compare function which includes functionality for the Turkish alphabet or other different languages than english.

public <K extends Comparable,V extends Comparable> LinkedHashMap<K,V> sortByKeys(LinkedHashMap<K,V> map){
    List<K> keys = new LinkedList<K>(map.keySet());
    Collections.sort(keys, (Comparator<? super K>) new Comparator<String>() {
        @Override
        public int compare(String first, String second) {
            Collator collator = Collator.getInstance(Locale.getDefault());
            //Collator collator = Collator.getInstance(new Locale("tr", "TR"));
            return collator.compare(first, second);
        }
    });

    LinkedHashMap<K,V> sortedMap = new LinkedHashMap<K,V>();
    for(K key: keys){
        sortedMap.put(key, map.get(key));
    }

    return sortedMap;
}

here is the using example as the following

LinkedHashMap<String, Boolean> ligList = new LinkedHashMap<String, Boolean>();
ligList = sortByKeys(ligList);
Share:
427,098
Admin
Author by

Admin

Updated on July 25, 2022

Comments

  • Admin
    Admin almost 2 years

    How are we able to sort a HashMap<key, ArrayList>?

    I want to sort on the basis of a value in the ArrayList.

  • Admin
    Admin about 15 years
    we have to sort only based on one element of the array list in the hash map hashmap map<key,arraylist>
  • Smashery
    Smashery about 15 years
    Yeah, it sounds like what you want is what the other guys are saying - TreeMap. TreeMaps seem much like HashMaps, except you can also sort them. Hooray!
  • Admin
    Admin about 15 years
    if we are storing in the hash map(key,person) person is a class its having four objects if we want sort based one one of the objects how we will do that...?
  • Mark Bennett
    Mark Bennett over 12 years
    A few more points: First, there are two decisions you need to make: (1) Whether you want to sort by the values, or by the keys, (2) Whether you have control over the collection at the start, so you can use built-in sorting, vs. when you're handed existing Maps and just want to iterate through them in some order. Also, the LinkedHashMap can maintain by insertion order (which I often like for debugging), or by access order. And finally if you're doing a lot of this you might check out Java 1.6 and NavigableMap, awesome stuff!
  • MAbraham1
    MAbraham1 over 10 years
    Why must we add a new library to perform a function that could be available natively?
  • Marquinho Peli
    Marquinho Peli over 7 years
    If you want to sort by keys use a SortedMap instead. It gives you automatic sorted keys.
  • Mathias G.
    Mathias G. about 7 years
    Java 8 comparator can be rewritten as: Comparator<Map.Entry<String, String>> valueComparator = Comparator.comparing(Map.Entry::getValue().getField());
  • vedi0boy
    vedi0boy almost 7 years
    TreeMap was the answer I was looking for when I came here so thank you.
  • ArtOfWarfare
    ArtOfWarfare over 6 years
    TreeMap seems like a really poor choice of name for the class... should be something like SortedMap instead. From the name, I'd think it's not a Map at all but some kind of Tree... the Tree part of TreeMap is really more of an implementation detail that shouldn't concern the user of the class at all.
  • pgras
    pgras over 6 years
    @ArtOfWarfare: Exactly the Tree is an implementation detail and therefore should concern the user when he chooses which class to use to implement the SortedMap interface...
  • Buffalo
    Buffalo about 6 years
    This isn't really a class. Also, your sorted values are stored in entryList, why are you clearing unSortedMap and printing it again? I suggest making a method named something like sortMap that has unSortedMap as param and returns entryList.
  • gokhansari
    gokhansari almost 6 years
    Would you please share the reason? @andrew
  • Constantine1991
    Constantine1991 about 5 years
    but we aren't providing anything to specify ascending/descending and sort by value.