Java中如何通过key和value对HashMap进行排序
在 Java 中对 HashMap
进行排序并不像听起来那么容易,因为不幸的是,Java API 没有提供任何实用方法来根据键和值对 HashMap 进行排序。 对 HashMap 进行排序不像在 Java 中对 ArrayList
或数组进行排序。 如果大家想知道为什么我们不能使用 Collections.sort()
方法而不是为了它只接受 List<E>
的信息,这让我们可以编写自己的实用方法来在 Java 中对 Map 进行排序。 这适用于所有类型的映射,如 Hashtable、HashMap 和 LinkedHashMap。 TreeMap 已经是一个排序好的Map,所以我们不需要再对它进行排序。
Java中为什么要对 HashMap 进行排序,为什么不能用 TreeMap 代替 HashMap 是大多数Java程序员在问到Java中对 HashMap 进行排序时都会出现在脑海中的问题。
好吧,TreeMap 比 HashMap 慢得多,因为它在每次插入、更新和删除时都运行排序操作,有时你并不真的需要一个一直排序的 Map,你需要的是能够根据其对任何 Map 实现进行排序的能力 键和值。
在本篇 Java 文章中,我们将看到几种在 Java 中对 HashMap
进行排序的方法。
在 Java 中排序 Map - 按键
正如我所说,Java 中的 Map 或 HashMap 可以按键或值排序。 按键对 Map 排序比按值排序更容易,因为 Map 允许重复值但不允许重复键。
我们可以通过将键复制到列表而不是使用 Collections.sort()
方法对列表进行排序来对 Map(无论是 HashMap 还是 Hashtable)进行排序,在这里我们可以根据要按自定义顺序还是自然顺序进行排序来使用 Comparator
或 Comparable
。
对键列表进行排序后,我们可以创建另一个 Map,特别是 LinkedHashMap
以按排序顺序插入键。 LinkedHashMap
将维护键插入的顺序,结果是一个基于键排序的 Map。
这在以下示例中通过编写通用参数化方法来根据键对 Map 进行排序来显示。 我们还可以使用 TreeMap 和 Google Collection API (Guava) 在 Java 中对 Map 进行排序。 使用 Guava 的优点是我们可以灵活地指定顺序。
在 Java 中对 Map 进行排序 - 按值
在 Java 中排序 Map,例如 基于值的 HashMap 或 Hashtable 比基于键对 Map 排序更困难,因为 Map 允许重复值,并且我们还面临处理空值的挑战。
package test;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
public class MapSortingExample {
public static void main(String args[]) {
//创建用于排序的哈希表
Map<String, Integer> olympic2012 = new HashMap<String, Integer>();
olympic2012.put("England", 3);
olympic2012.put("USA", 1);
olympic2012.put("China", 2);
olympic2012.put("Russia", 4);
//olympic2012.put("Australia", 4); //添加重复值
//不排序打印哈希表
System.out.println("Unsorted Map in Java : " + olympic2012);
//排序Map 例如 HashMap,Java 中的按键哈希表
Map<String, Integer> sorted = sortByKeys(olympic2012);
System.out.println("Sorted Map in Java by key: " + sorted);
//在 Java 中按值对 Hashtable 和 HashMap 等 Map 进行排序
sorted = sortByValues(olympic2012);
System.out.println("Sorted Map in Java by values: " + sorted);
//使用 TreeMap 按键对 Java 中的 Map 进行排序
Map<String, Integer> sortedMapByKeys = new TreeMap<String,Integer>();
sortedMapByKeys.putAll(olympic2012);
System.out.println("Sorted Map in Java by key using TreeMap : " + sortedMapByKeys);
// 使用 Google Collections (Guava) 在 Java 中按键对 Map 进行排序
// 主要好处是我们可以指定任何顺序,如自然或 toString 或任意
Map<String, Integer> sortingUsingGuava = Maps.newTreeMap(Ordering.natural());
sortingUsingGuava.putAll(olympic2012);
System.out.println("Example to sort Map in Java using Guava : " + sortingUsingGuava);
}
/*
* 对 Map 进行排序的参数化方法,例如 如果 Map 包含空键,
* Java 中的 HashMap 或 Hashtable 会抛出 NullPointerException
*/
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByKeys(Map<K,V> map){
List<K> keys = new LinkedList<K>(map.keySet());
Collections.sort(keys);
// LinkedHashMap 将按照插入的顺序保存键
// 该顺序当前按自然顺序排序
Map<K,V> sortedMap = new LinkedHashMap<K,V>();
for(K key: keys){
sortedMap.put(key, map.get(key));
}
return sortedMap;
}
/*
* Java 方法按值对 Java 中的 Map 进行排序,
* 例如 如果 Map 包含空值,HashMap 或 Hashtable 会抛出 NullPointerException 它也会对值进行排序,
* 即使它们是重复的
*/
public static <K extends Comparable,V extends Comparable> Map<K,V> sortByValues(Map<K,V> map){
List<Map.Entry<K,V>> entries = new LinkedList<Map.Entry<K,V>>(map.entrySet());
Collections.sort(entries, new Comparator<Map.Entry<K,V>>() {
@Override
public int compare(Entry<K, V> o1, Entry<K, V> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
// LinkedHashMap 将按照插入的顺序保存键
// 该顺序当前按自然顺序排序
Map<K,V> sortedMap = new LinkedHashMap<K,V>();
for(Map.Entry<K,V> entry: entries){
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
}
以上代码输出结果如下
Unsorted Map in Java : {USA=1, England=3, Russia=4, China=2}
Sorted Map in Java by key: {China=2, England=3, Russia=4, USA=1}
Sorted Map in Java by values: {USA=1, China=2, England=3, Russia=4}
Sorted Map in Java by key using TreeMap : {China=2, England=3, Russia=4, USA=1}
Example to sort Map in Java using Guava : {China=2, England=3, Russia=4, USA=1}
这就是如何在 Java 中按键和值对 Map 进行排序的全部内容。 我们已经学习了如何根据键和值对映射实现(如 HashMap、Hashtable)进行排序。 请记住,基于值对 Map 进行排序比基于键对 Map 进行排序更困难,因为 Map 中的值可以为 null 或重复,而键不是这种情况。
相关文章
在 Java 中获取文件大小
发布时间:2023/05/01 浏览次数:139 分类:Java
-
Java 提供了不同的方法来获取文件的字节大小。 本教程演示了在 Java 中获取文件大小的不同方法。使用 Java IO 的文件类获取文件大小 Java IO 包的 File 类提供了以字节为单位获取文件大小的功能。
Java 中的文件分隔符
发布时间:2023/05/01 浏览次数:108 分类:Java
-
本篇文章介绍了 Java 中的文件分隔符。Java 中的文件分隔符 文件分隔符是用来分隔目录的字符; 例如,Unix 使用 /,Windows 使用 \ 作为文件分隔符。
Java 中的文件过滤器
发布时间:2023/05/01 浏览次数:193 分类:Java
-
本篇文章介绍如何在 Java 中使用 FileFilter。FileFilter 用于过滤具有特定扩展名的文件。 Java内置包IO和Apache Commons IO为FileFilter提供了类和接口来进行文件过滤操作。
Java 获取 ISO 8601 格式的当前时间戳
发布时间:2023/05/01 浏览次数:132 分类:Java
-
本篇文章介绍了 ISO 8601 日期格式、其重要性及其在 Java 中的使用。 它还列出了一些优点来强调为什么应该使用 ISO 格式来表示日期。
在 Java 中获取数组的子集
发布时间:2023/05/01 浏览次数:142 分类:Java
-
本篇文章介绍了几种在 Java 中获取数组子集的方法。使用 Arrays.copyOf() 方法获取数组的子集 使用 Arrays.copyOfRange() 方法获取数组的子集
用 Java 填充二维数组
发布时间:2023/05/01 浏览次数:110 分类:Java
-
二维数组是基于表结构的,即行和列,填充二维数组不能通过简单的添加到数组操作来完成。 本篇文章介绍如何在 Java 中填充二维数组。
计算 Java 数组中的重复元素
发布时间:2023/05/01 浏览次数:202 分类:Java
-
本篇文章介绍Java计算数组中重复元素的方法。计算 Java 数组中的重复元素。我们可以创建一个程序来计算数组中的重复元素。 该数组可以是未排序的,也可以是已排序的。
Java 中 List 和 Arraylist 的区别
发布时间:2023/05/01 浏览次数:90 分类:Java
-
表示为单个单元的一组单个对象称为集合。 在 Java 中,Collection 是一个具有多个已定义接口和类的框架,用于将一组对象表示为一个单元。 它允许我们操纵