• 欢迎访问天天编码网站,Java技术、技术书单、开发工具,欢迎加入天天编码
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏天天编码吧
  • 我们的淘宝店铺已经开张了哦,传送门:https://shop145764801.taobao.com/

Java的HashMap如何按值(Value)排序

Java基础 tiantian 2433次浏览 0个评论 扫描二维码

在Java中,如果我们需要对一个Map集合按照键进行元素排序,我们可以直接选择使用JDK中的 TreeMap 集合。这个集合可以非常方便地实现元素的按键排序。然后,在实际项目过程中,我们可能需要按照Map的值(Value)来排序HashMap集合的元素。实际上,按照值来排序HashMap的元素是一个并不罕见的需求。本文,将提供一个解决此问题的最佳方法。

Java的HashMap如何按值(Value)排序

简单方法

假设,我们需要排序一个元素类型为 <String, Integer> 的HashMap,给出简单的示例代码如下:

public class SortMapByValue {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
hashMap.put("a", 10);
hashMap.put("b", 30);
hashMap.put("c", 50);
hashMap.put("d", 40);
hashMap.put("e", 20);

System.out.println(hashMap);
TreeMap<String, Integer> sortedMap = sortMapByValue(hashMap);
System.out.println(sortedMap);
}

publi static TreeMap<String, Integer> sortMapByValue(HashMap<String, Integer> hashMap) {
Comparator comparator = new ValueComparator(hashMap);
TreeMap<String, Integer> result = new TreeMap<String, Integer>(comparator);
result.putAll(hashMap);
return result;
}
}

此解决方法的关键在于 ValueComparator 的实现细节:

class ValueComparator implements Comparator {
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();

public ValueComparator(HashMap<String, Integer> hashMap) {
this.hashMap.putAll(hashMap);
}

@Override
public int compare(String s1, String s2) {
if (hashMap.get(s1) >= hashMap.get(s2)) {
return -1;
} else {
return 1;
}
}
}

此处,我们巧妙地利用了TreeMap的键排序特性和定制化Compatator。当我们创建一个TreeMap时,同时,给予其一个我们定制化的 comparator。在该 comparator 中,它接受 String 类型的参数,并且利用该参数去 HashMap中获取对应的值,并且以值的比较结果作为该 comparator 的比较结果。

这个方法完全可以实现功能,而且整体的思路比较清晰和简单。但是,这个方法只能用来完成元素类型为 <String, Integer> 的HashMap的按值排序。如果,读者需要可以按值比较其他元素类型的HashMap集合,我们需要重写很多代码。应此,我们考虑使用一个更加通用的解决方案。

改进方案

上述的简单方案存在的缺点就是通用性不够,我们可以直接忽略掉元素的类型,从而使其适用与任何元素类型:

public class Solution {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
hashMap.put("a", 10);
hashMap.put("b", 30);
hashMap.put("c", 50);
hashMap.put("d", 40);
hashMap.put("e", 20);

System.out.println(hashMap);
Map sortedMap = sortMapByValue(hashMap);
System.out.println(sortedMap);
}

public static Map sortByValue(Map map) {
Map sortedMap = new TreeMap(new ValueComparator(map));
sortedMap.putAll(map);
return sortedMap;
}
}

class ValueComparator implements Comparator {
Map map;

public ValueComparator(Map map) {
this.map = map;
}

public int compare(Object keyA, Object keyB) {
Comparable valueA = (Comparable) map.get(keyA);
Comparable valueB = (Comparable) map.get(keyB);
return valueB.compareTo(valueA);
}
}

完美方法

上述的改进方法虽然同样了,但是却是类型不安全的。我们来看看使用泛型改进后的类型安全的完美解决方案。

public class Solution {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
hashMap.put("a", 10);
hashMap.put("b", 30);
hashMap.put("c", 50);
hashMap.put("d", 40);
hashMap.put("e", 20);

System.out.println(hashMap);
Comparator comparator = new ValueComparator<String, Integer>(hashMap);
TreeMap<String, Integer> result = new TreeMap<String, Integer>(comparator);
result.putAll(hashMap);
System.out.println(sortedMap);
}
}

我们看看如何利用泛型实现类型安全的 ValueComparator :

class ValueComparator<K, V extends Comparable> implements Comparator {
HashMap<K, V> hashMap = new HashMap<K, V>();

public ValueComparator(HashMap<K, V> hashMap) {
this.hashMap.putAll(hashMap);
}

@Override
public int compare(K k1, K k2) {
return hashMap.get(k2).compareTo(hashMap.get(k1));
}
}

终极方法

使用泛型,我们还可以写出另一个利用 Collections 的排序功能的解决方案:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
@Override
public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
return (e1.getValue()).compareTo(e2.getValue());
}
});

Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}

return result;
}

天天编码 , 版权所有丨本文标题:Java的HashMap如何按值(Value)排序
转载请保留页面地址:http://www.tiantianbianma.com/java-hashmap-order.html/
喜欢 (7)
支付宝[多谢打赏]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址