Java面试题:如何对HashMap按键值排序

简介:

Java中HashMap是一种用于存储“键”和“值”信息对的数据结构。不同于Array、ArrayList和LinkedLists,它不会维持插入元素的顺序。
因此,在键或值的基础上排序HashMap是一个很难的面试问题,如果你不知道如何解决的话。下面让我们看看如何解决这个问题。

1. HashMap存储每对键和值作为一个Entry<K,V>对象。例如,给出一个HashMap,

 
  1. Map<String,Integer> aMap = new HashMap<String,Integer>(); 

键的每次插入,都会有值对应到散列映射上,生成一个Entry <K,V>对象。通过使用这个Entry <K,V>对象,我们可以根据值来排序HashMap。

2.创建一个简单的HashMap,并插入一些键和值。

 
  1. ap<String,Integer> aMap = new HashMap<String,Integer>(); 
  2.  
  3.         // adding keys and values 
  4.         aMap.put("Five"5); 
  5.         aMap.put("Seven"7); 
  6.         aMap.put("Eight"8); 
  7.         aMap.put("One",1); 
  8.         aMap.put("Two",2); 
  9.         aMap.put("Three"3); 

3.从HashMap恢复entry集合,如下所示。

 
  1. Set<Entry<String,Integer>> mapEntries = aMap.entrySet(); 

4.从上述mapEntries创建LinkedList。我们将排序这个链表来解决顺序问题。我们之所以要使用链表来实现这个目的,是因为在链表中插入元素比数组列表更快。

 
  1. List<Entry<String,Integer>> aList = new LinkedList<Entry<String,Integer>>(mapEntries); 

5.通过传递链表和自定义比较器来使用Collections.sort()方法排序链表。

 
  1. Collections.sort(aList, new Comparator<Entry<String,Integer>>() { 
  2.  
  3.             @Override 
  4.  
  5.             public int compare(Entry<String, Integer> ele1, 
  6.  
  7.                     Entry<String, Integer> ele2) { 
  8.  
  9.                 return ele1.getValue().compareTo(ele2.getValue()); 
  10.  
  11.             } 
  12.  
  13.         }); 

6.使用自定义比较器,基于entry的值(Entry.getValue()),来排序链表。

7. ele1.getValue(). compareTo(ele2.getValue())——比较这两个值,返回0——如果这两个值完全相同的话;返回1——如果第一个值大于第二个值;返回-1——如果第一个值小于第二个值。

8. Collections.sort()是一个内置方法,仅排序值的列表。它在Collections类中重载。这两种个方法是

 
  1. public static <T extends Comparable<? super T>> void sort(List<T> list) 
  2.  
  3. public static <T> void sort(List<T> list, Comparator<? super T> c) 

9.现在你已经排序链表,我们需要存储键和值信息对到新的映射中。由于HashMap不保持顺序,因此我们要使用LinkedHashMap。

 
  1. // Storing the list into Linked HashMap to preserve the order of insertion.      
  2. Map<String,Integer> aMap2 = new LinkedHashMap<String, Integer>(); 
  3.         for(Entry<String,Integer> entry: aList) { 
  4.             aMap2.put(entry.getKey(), entry.getValue()); 
  5.         } 

10.完整的代码如下。

 
  1. package com.speakingcs.maps; 
  2.  
  3. import java.util.Collections; 
  4. import java.util.Comparator; 
  5. import java.util.HashMap; 
  6. import java.util.LinkedHashMap; 
  7. import java.util.LinkedList; 
  8. import java.util.List; 
  9. import java.util.Map; 
  10. import java.util.Map.Entry; 
  11. import java.util.Set; 
  12.  
  13. public class SortMapByValues { 
  14.  
  15.     public static void main(String[] args) { 
  16.  
  17.         Map<String,Integer> aMap = new HashMap<String,Integer>(); 
  18.  
  19.         // adding keys and values 
  20.         aMap.put("Five"5); 
  21.         aMap.put("Seven"7); 
  22.         aMap.put("Eight"8); 
  23.         aMap.put("One",1); 
  24.         aMap.put("Two",2); 
  25.         aMap.put("Three"3); 
  26.  
  27.         sortMapByValues(aMap); 
  28.  
  29.     } 
  30.  
  31.     private static void sortMapByValues(Map<String, Integer> aMap) { 
  32.  
  33.         Set<Entry<String,Integer>> mapEntries = aMap.entrySet(); 
  34.  
  35.         System.out.println("Values and Keys before sorting "); 
  36.         for(Entry<String,Integer> entry : mapEntries) { 
  37.             System.out.println(entry.getValue() + " - "+ entry.getKey()); 
  38.         } 
  39.  
  40.         // used linked list to sort, because insertion of elements in linked list is faster than an array list. 
  41.         List<Entry<String,Integer>> aList = new LinkedList<Entry<String,Integer>>(mapEntries); 
  42.  
  43.         // sorting the List 
  44.         Collections.sort(aList, new Comparator<Entry<String,Integer>>() { 
  45.  
  46.             @Override 
  47.             public int compare(Entry<String, Integer> ele1, 
  48.                     Entry<String, Integer> ele2) { 
  49.  
  50.                 return ele1.getValue().compareTo(ele2.getValue()); 
  51.             } 
  52.         }); 
  53.  
  54.         // Storing the list into Linked HashMap to preserve the order of insertion. 
  55.         Map<String,Integer> aMap2 = new LinkedHashMap<String, Integer>(); 
  56.         for(Entry<String,Integer> entry: aList) { 
  57.             aMap2.put(entry.getKey(), entry.getValue()); 
  58.         } 
  59.  
  60.         // printing values after soring of map 
  61.         System.out.println("Value " + " - " + "Key"); 
  62.         for(Entry<String,Integer> entry : aMap2.entrySet()) { 
  63.             System.out.println(entry.getValue() + " - " + entry.getKey()); 
  64.         } 
  65.  
  66.     } 


作者:小峰

来源:51CTO

相关文章
|
20天前
|
缓存 Java 关系型数据库
【Java面试题汇总】ElasticSearch篇(2023版)
倒排索引、MySQL和ES一致性、ES近实时、ES集群的节点、分片、搭建、脑裂、调优。
【Java面试题汇总】ElasticSearch篇(2023版)
|
12天前
|
设计模式 Java
结合HashMap与Java 8的Function和Optional消除ifelse判断
`shigen`是一位致力于记录成长、分享认知和留住感动的博客作者。本文通过具体代码示例探讨了如何优化业务代码中的if-else结构。首先展示了一个典型的if-else处理方法,并指出其弊端;然后引入了策略模式和工厂方法等优化方案,最终利用Java 8的Function和Optional特性简化代码。此外,还提到了其他几种消除if-else的方法,如switch-case、枚举行、SpringBoot的IOC等。一起跟随shigen的脚步,让每一天都有所不同!
27 10
结合HashMap与Java 8的Function和Optional消除ifelse判断
|
19天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
174 37
|
20天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
20天前
|
存储 关系型数据库 MySQL
【Java面试题汇总】MySQL数据库篇(2023版)
聚簇索引和非聚簇索引、索引的底层数据结构、B树和B+树、MySQL为什么不用红黑树而用B+树、数据库引擎有哪些、InnoDB的MVCC、乐观锁和悲观锁、ACID、事务隔离级别、MySQL主从同步、MySQL调优
【Java面试题汇总】MySQL数据库篇(2023版)
|
20天前
|
存储 缓存 NoSQL
【Java面试题汇总】Redis篇(2023版)
Redis的数据类型、zset底层实现、持久化策略、分布式锁、缓存穿透、击穿、雪崩的区别、双写一致性、主从同步机制、单线程架构、高可用、缓存淘汰策略、Redis事务是否满足ACID、如何排查Redis中的慢查询
【Java面试题汇总】Redis篇(2023版)
|
20天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
20天前
|
缓存 Java 数据库
【Java面试题汇总】Spring篇(2023版)
IoC、DI、aop、事务、为什么不建议@Transactional、事务传播级别、@Autowired和@Resource注解的区别、BeanFactory和FactoryBean的区别、Bean的作用域,以及默认的作用域、Bean的生命周期、循环依赖、三级缓存、
【Java面试题汇总】Spring篇(2023版)
|
20天前
|
存储 缓存 监控
【Java面试题汇总】JVM篇(2023版)
JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优
【Java面试题汇总】JVM篇(2023版)
|
8天前
|
消息中间件 NoSQL Java
Java知识要点及面试题
该文档涵盖Java后端开发的关键知识点,包括Java基础、JVM、多线程、MySQL、Redis、Spring框架、Spring Cloud、Kafka及分布式系统设计。针对每个主题,文档列举了重要概念及面试常问问题,帮助读者全面掌握相关技术并准备面试。例如,Java基础部分涉及面向对象编程、数据类型、异常处理等;JVM部分则讲解内存结构、类加载机制及垃圾回收算法。此外,还介绍了多线程的生命周期、同步机制及线程池使用,数据库设计与优化,以及分布式系统中的微服务、RPC调用和负载均衡等。
下一篇
无影云桌面