Java HashMap按值排序:终极指南与实用技巧

这是文章《在Java中如何根据值对HashMap进行排序?》的第1部分(共4部分)。

Java中的HashMap提供了快速查找功能,它们以“键值对”(key-value pairs)的形式存储数据项。要从HashMap中获取一个值,我们使用与该条目对应的键。

HashMap是实现字典和目录的优秀选择。

键和值可以是不同类型的数据(例如,字符串、整数)。

我们可以根据键和值对HashMap中的条目进行排序。

在本教程中,我们将重点介绍如何根据值对HashMap进行排序。

基本策略是:首先从HashMap中提取所有值,并将它们放入一个列表中进行排序。如果值的数据类型是String,我们将使用比较器(Comparator)对列表进行排序。要了解更多关于比较器的信息,请阅读本教程

一旦我们获得了按顺序排列的值列表,我们将根据这个排序后的列表重新构建HashMap

让我们来看一下代码实现。

HashMap按值排序的简单示例

我们首先将字符串值放入一个列表中,然后对该列表进行排序。

为了对列表中的字符串值进行排序,我们使用一个比较器(Comparator)。这个比较器将按字母顺序对值列表进行排序。

Collections.sort(list, new Comparator<String>() {
            public int compare(String str, String str1) {
                return (str).compareTo(str1);
            }
        });

在我们排序完列表之后,我们根据这个排序好的列表构建HashMap

完整的代码如下:

package com.scdev.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;


public class Main {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        LinkedHashMap<String, String> sortedMap = new LinkedHashMap<>();
        ArrayList<String> list = new ArrayList<>();
        map.put("2", "B");
        map.put("8", "A");
        map.put("4", "D");
        map.put("7", "F");
        map.put("6", "W");
        map.put("19", "J");
        map.put("1", "Z");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            list.add(entry.getValue());
        }
        Collections.sort(list, new Comparator<String>() {
            public int compare(String str, String str1) {
                return (str).compareTo(str1);
            }
        });
        for (String str : list) {
            for (Entry<String, String> entry : map.entrySet()) {
                if (entry.getValue().equals(str)) {
                    sortedMap.put(entry.getKey(), str);
                }
            }
        }
        System.out.println(sortedMap);
    }
}

输出:

{8=A, 5=B, 3=D, 7=F, 10=J, 2=W, 1=Z}
值类型为字符串

HashMap的条目根据其值进行排序。

根据值对HashMap进行排序的另一个示例:当HashMap的值为整型(Integer)时

如果HashMap中的值是整型(Integer),代码示例如下:

package com.JournalDev;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;


public class Main {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        LinkedHashMap<String, Integer> sortedMap = new LinkedHashMap<>();
        ArrayList<Integer> list = new ArrayList<>();
        map.put("A", 5);
        map.put("B", 7);
        map.put("C", 3);
        map.put("D", 1);
        map.put("E", 2);
        map.put("F", 8);
        map.put("G", 4);
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            list.add(entry.getValue());
        }
        Collections.sort(list); 
        for (int num : list) {
            for (Entry<String, Integer> entry : map.entrySet()) {
                if (entry.getValue().equals(num)) {
                    sortedMap.put(entry.getKey(), num);
                }
            }
        }
        System.out.println(sortedMap);
    }
}

输出:

{D=1, E=2, C=3, G=4, A=5, B=7, F=8}
值为整型

使用自定义比较器对HashMap进行排序

在前面的例子中,我们看到Value对象实现了Comparator接口,并根据整数值对HashMap进行了排序。现在,让我们来看一个值是自定义对象的例子。

我们还可以创建一个自定义比较器来根据值对哈希映射进行排序。当值是自定义对象时,这种方法将非常有用。

让我们举一个例子,假设值是一个名为“Name”的类。这个类有两个参数:名字(firstName)和姓氏(lastName)。

Name类的代码如下:

package com.JournalDev;

public class Name {
   String firstName;
   String lastName;
   Name(String a, String b){
       firstName=a;
       lastName=b;

   }
    public String getFirstName() {
        return firstName;
    }


}

自定义的比较器将类似于:

Comparator<Name> byName = (Name obj1, Name obj2) -> obj1.getFirstName().compareTo(obj2.getFirstName());

我们正在按照名字(firstName)的顺序进行排序,当然也可以使用姓氏(lastName)来排序。为了避免先将值放入列表中再进行排序,我们将直接使用LinkedHashMap来创建已排序的哈希映射。

完整的代码如下:

public static void main(String[] args) {
        HashMap<Integer, Name> hmap = new HashMap<Integer, Name>();
        Name name1 = new Name("Jayant", "Verma");
        Name name2 = new Name("Ajay", "Gupta");
        Name name3 = new Name("Mohan", "Sharma");
        Name name4 = new Name("Rahul", "Dev");


        hmap.put(9, name1);
        hmap.put(1, name2);
        hmap.put(6, name3);
        hmap.put(55, name4);

        Comparator<Name> byName = (Name obj1, Name obj2) -> obj1.getFirstName().compareTo(obj2.getFirstName());

        LinkedHashMap<Integer, Name> sortedMap = hmap.entrySet().stream()
                .sorted(Map.Entry.<Integer, Name>comparingByValue(byName))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
        
// 打印排序后的哈希映射 
        Set set = sortedMap.entrySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry me2 = (Map.Entry) iterator.next();
            System.out.print(me2.getKey() + ": ");
         System.out.println(hmap.get(me2.getKey()).firstName + " "+hmap.get(me2.getKey()).lastName );
          
        }
    }

输出结果:

1: Ajay Gupta
9: Jayant Verma
6: Mohan Sharma
55: Rahul Dev
自定义比较器

结论

本教程详细介绍了如何在Java中根据值对HashMap进行排序。值得注意的是,根据字符串值进行排序与根据整数值进行排序的方法有所不同。对于字符串值,通常需要借助自定义比较器(Comparator)来实现排序逻辑。而对于整数值,则可以直接利用Collections.sort()方法进行排序,因为它能够处理基本数据类型的包装类或实现了Comparable接口的对象。

bannerAds