Java中HashMap是一种用于存储“键”和“值”信息对的数据结构。不同于Array、ArrayList和LinkedLists,它不会维持插入元素的顺序。

因此,在键或值的基础上排序HashMap是一个很难的面试问题,如果你不知道如何解决的话。下面让我们看看如何解决这个问题。

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

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

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

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

ap<String,Integer> aMap = new HashMap<String,Integer>();

        // adding keys and values
        aMap.put("Five", 5);
        aMap.put("Seven", 7);
        aMap.put("Eight", 8);
        aMap.put("One",1);
        aMap.put("Two",2);
        aMap.put("Three", 3);

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

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

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

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

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

Collections.sort(aList, new Comparator<Entry<String,Integer>>() {

            @Override

            public int compare(Entry<String, Integer> ele1,

                    Entry<String, Integer> ele2) {

                return ele1.getValue().compareTo(ele2.getValue());

            }

        });

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

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

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

public static <T extends Comparable<? super T>> void sort(List<T> list)

public static <T> void sort(List<T> list, Comparator<? super T> c)

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

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

10.完整的代码如下。

package com.speakingcs.maps;

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.Set; public class SortMapByValues {     public static void main(String[] args) {         Map<String,Integer> aMap = new HashMap<String,Integer>();         // adding keys and values
        aMap.put("Five", 5);
        aMap.put("Seven", 7);
        aMap.put("Eight", 8);
        aMap.put("One",1);
        aMap.put("Two",2);
        aMap.put("Three", 3);         sortMapByValues(aMap);     }     private static void sortMapByValues(Map<String, Integer> aMap) {         Set<Entry<String,Integer>> mapEntries = aMap.entrySet();         System.out.println("Values and Keys before sorting ");
        for(Entry<String,Integer> entry : mapEntries) {
            System.out.println(entry.getValue() + " - "+ entry.getKey());
        }         // used linked list to sort, because insertion of elements in linked list is faster than an array list.
        List<Entry<String,Integer>> aList = new LinkedList<Entry<String,Integer>>(mapEntries);         // sorting the List
        Collections.sort(aList, new Comparator<Entry<String,Integer>>() {             @Override
            public int compare(Entry<String, Integer> ele1,
                    Entry<String, Integer> ele2) {                 return ele1.getValue().compareTo(ele2.getValue());
            }
        });         // Storing the list into Linked HashMap to preserve the order of insertion.
        Map<String,Integer> aMap2 = new LinkedHashMap<String, Integer>();
        for(Entry<String,Integer> entry: aList) {
            aMap2.put(entry.getKey(), entry.getValue());
        }         // printing values after soring of map
        System.out.println("Value " + " - " + "Key");
        for(Entry<String,Integer> entry : aMap2.entrySet()) {
            System.out.println(entry.getValue() + " - " + entry.getKey());
        }     }
}

Java面试题:如何对HashMap按键值排序的更多相关文章

  1. 如何对HashMap按键值排序

    Java中HashMap是一种用于存储“键”和“值”信息对的数据结构.不同于Array.ArrayList和LinkedLists,它不会维持插入元素的顺序. 因此,在键或值的基础上排序HashMap ...

  2. 【Java面试题】33 HashMap和Hashtable的区别

    1 HashMap不是线程安全的 hastmap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值.HashMap允许null key和n ...

  3. java面试题之为什么hashmap的数组初始化大小都是2的N次方?

    当数组长度为2的N次方时,不同的key算出的index相同的几率小,数据在数组上分配均匀,hash碰撞的几率小,提升查询效率,从大O(N)提升至O(1):

  4. java算法面试题:有一个字符串,其中包含中文字符、英文字符和数字字符,请统计和打印出各个字符的个数 按值的降序排序,如果值相同则按键值的字母顺序

    package com.swift; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; publi ...

  5. 阿里腾讯校招Java面试题总结及答案

    阿里校招java面试题汇总 1.HashMap和HashTable的区别,及其实现原理. Hashtable继承自Dictionary类,而HashMap是Java1.2引进的,继承自Abstract ...

  6. [Java集合] 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享. 原文地址: http://blog.csdn.net/zhanger ...

  7. 【转载】关于Java String, StringBuilder, StringBuffer, Hashtable, HashMap的面试题

    REF: http://blog.csdn.net/fightforyourdream/article/details/15333405 题目是一道简单的小程序,像下面这样:[java] view p ...

  8. Java面试题之HashMap阿里面试必问知识点,你会吗?

    面试官Q1:你用过HashMap,你能跟我说说它的数据结构吗? HashMap作为一种容器类型,无论你是否了解过其内部的实现原理,它的大名已经频频出现在各种互联网Java面试题中了.从基本的使用角度来 ...

  9. java面试题——HashMap和Hashtable 的区别

    一.HashMap 和Hashtable 的区别 我们先看2个类的定义 public class Hashtable extends Dictionary implements Map, Clonea ...

随机推荐

  1. GCD汇总

    //总结如下: //1.同步请求:不会开启新的线程 //1-1.同步请求--串行队列:不开启新线程--按照顺序执行下去 //1-2.同步请求--并发列队:不开启新线程--按照顺序执行下去 //2.异步 ...

  2. IT行业的一些专业术语

    SDK:SDK(Software Development Kit, 即软件开发工具包 )一般是一些被软件工程师用于为特定的软件包.软件框架.硬件平台.操作系统等建立应用软件的开发工具的集合. 参考:h ...

  3. NumPy数组创建例程

    NumPy - 数组创建例程 新的ndarray对象可以通过任何下列数组创建例程或使用低级ndarray构造函数构造. numpy.empty 它创建指定形状和dtype的未初始化数组. 它使用以下构 ...

  4. Eclipse2013_文件编码设置

    1. Eclipse --> Window --> Preferences --> General --> Workspace 其中的 "Text file enco ...

  5. java8 日期处理

    这两周写业务逻辑,总会有各种日期操作,但是又记不住API,就是记不住API啊 这篇博客不错,记下来 https://lw900925.github.io/java/java8-newtime-api. ...

  6. c#实现验证某个IP地址是否能ping通

    using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net ...

  7. Educational Codeforces Round 38

    http://codeforces.com/contest/938 A:sb题 //#pragma comment(linker, "/stack:200000000") //#p ...

  8. [转载]java操作word生成水印

    应用场景 为了保护版权或辨别文件的真伪,有时需要在生成的Word文件中动态添加水印,PageOffice组件的WaterMark类就封装了给在线编辑的Word文件添加水印这一功能,调用接口非常简单. ...

  9. sql日期函数总结

    sql 时间转换格式 convert(varchar(10),字段名,转换格式)   convert(varchar(10),字段名,转换格式) CONVERT(nvarchar(10),count_ ...

  10. C++友元类实现

    C++中的友元既可以实现友元函数,也可以实现友元类,也就是说一个类也可以作为另外一个类的友元.当作为一个类的友元时,它的所有成员函数都是另一个类的友元函数,都可以访问另一个类的私有或者公有成员. 请看 ...