(java基础知识)HashMap排序,Comparator接口详解

2023-10-27

对于List,可以调用Collections工具类的sort()方法,直接进行排序。HashMap,就没这么幸福了。。
其实,只要了解了Comparator这个接口之后,HashMap的排序也就不难了,无论是根据key,还是根据value排序。
这个接口也很简单,只有一个抽象方法int compare();需要我们去实现。这个方法,就是实现你制订的比较规则。(其实这个接口里面还有一个方法boolean equals()但是API里面说不是现在这个方法也总是安全的。。这个方法只有当你的程序有两个以上的Comparator的实现之后才用的上,用于比较)
具体去实现的时候,有两种常用途径。
1、匿名内部类
这是最简单实用的一种方法了。为了方便实现根据key和value的排序,我把这个map设计成Map<Integer,Integer>

  1. import java.util.*;
  2. class Test
  3. {
  4. public static void main(String[] args)
  5. {
  6. Map<Integer,Integer> map=new HashMap<>();
  7. map.put(1,2);
  8. map.put(8,3);
  9. map.put(3,4);
  10. map.put(5,7);
  11. map.put(4,6);
  12. map.put(9,8);
  13. //这一步很关键,因为要利用sort(List<T> list,Comparator<? super T> c)方法。
  14. List<Map.Entry<Integer,Integer>> list=new ArrayList<>();
  15. //把map转化为Map.Entry然后放到用于排序的list里面
  16. list.addAll(map.entrySet());
  17. //开始排序了,利用匿名内部类,直接创建Comparator接口的对象,不用再写实现类了。
  18. Collections.sort(list,new Comparator<Map.Entry<Integer,Integer>>()
  19. {
  20. public int compare(Map.Entry<Integer,Integer> m,Map.Entry<Integer,Integer> n)
  21. {
  22. //比较的规则,这是根据key,从小到大排序。如果从大到小就调换m和n的位置。
  23. return m.getKey()-n.getKey();
  24. }
  25. });
  26. //遍历在list中排序之后的HashMap
  27. for(Iterator<Map.Entry<Integer,Integer>> it=list.iterator();it.hasNext();)
  28. {
  29. System.out.println(it.next());
  30. }
  31. }
  32. }
import java.util.*;
class Test
{
	public static void main(String[] args) 
	{
		Map<Integer,Integer> map=new HashMap<>();
		map.put(1,2);
		map.put(8,3);
		map.put(3,4);
		map.put(5,7);
		map.put(4,6);
		map.put(9,8);
		//这一步很关键,因为要利用sort(List<T> list,Comparator<? super T> c)方法。
		List<Map.Entry<Integer,Integer>> list=new ArrayList<>();
		//把map转化为Map.Entry然后放到用于排序的list里面
		list.addAll(map.entrySet());
		//开始排序了,利用匿名内部类,直接创建Comparator接口的对象,不用再写实现类了。
		Collections.sort(list,new Comparator<Map.Entry<Integer,Integer>>()
		{
			public int compare(Map.Entry<Integer,Integer> m,Map.Entry<Integer,Integer> n)
			{
				//比较的规则,这是根据key,从小到大排序。如果从大到小就调换m和n的位置。
				return m.getKey()-n.getKey();
			}
		});
		//遍历在list中排序之后的HashMap
		for(Iterator<Map.Entry<Integer,Integer>> it=list.iterator();it.hasNext();)
		{
			System.out.println(it.next());
		}
	}
}

输出:

1=2
3=4
4=6
5=7
8=3
9=8


2、内部类/内部静态类
比起第一种方法,这种算是中规中矩的方法了。当然没有第一种简洁,但是更有利于我们理解Comparator这个接口。

  1. import java.util.*;
  2. class Test
  3. {
  4. //静态内部类
  5. private static class MyComparator implements Comparator<Map.Entry<Integer, String>>
  6. {
  7. public int compare(Map.Entry<Integer, String> m,Map.Entry<Integer, String> n)
  8. {
  9. //根据value排序,规则是字符串的长短
  10. return n.getValue().length()-m.getValue().length();
  11. }
  12. }
  13. public static void main(String[] args)
  14. {
  15. Map<Integer,String> map=new HashMap<>();
  16. map.put(1,"a");
  17. map.put(8,"bbb");
  18. map.put(3,"cc");
  19. map.put(5,"abcd");
  20. map.put(4,"a");
  21. map.put(9,"abcde");
  22. //这一步很关键,因为要利用sort(List<T> list,Comparator<? super T> c)方法。
  23. List<Map.Entry<Integer,String>> list=new ArrayList<>();
  24. //把map转化为Map.Entry然后放到用于排序的list里面
  25. list.addAll(map.entrySet());
  26. //调用内部类的构造器,如果这个内部类是静态内部类,就比这个好办点了。。
  27. Test.MyComparator mc=new MyComparator();
  28. //开始排序,传入比较器对象
  29. Collections.sort(list,mc);
  30. //遍历在list中排序之后的HashMap
  31. for(Iterator<Map.Entry<Integer,String>> it=list.iterator();it.hasNext();)
  32. {
  33. System.out.println(it.next());
  34. }
  35. }
  36. }
import java.util.*;
class Test
{
	//静态内部类
	private static class MyComparator implements Comparator<Map.Entry<Integer, String>>
	{
		public int compare(Map.Entry<Integer, String> m,Map.Entry<Integer, String> n)
		{
			//根据value排序,规则是字符串的长短
			return n.getValue().length()-m.getValue().length();
		}
	}
	public static void main(String[] args) 
	{
		Map<Integer,String> map=new HashMap<>();
		map.put(1,"a");
		map.put(8,"bbb");
		map.put(3,"cc");
		map.put(5,"abcd");
		map.put(4,"a");
		map.put(9,"abcde");
		//这一步很关键,因为要利用sort(List<T> list,Comparator<? super T> c)方法。
		List<Map.Entry<Integer,String>> list=new ArrayList<>();
		//把map转化为Map.Entry然后放到用于排序的list里面
		list.addAll(map.entrySet());
		//调用内部类的构造器,如果这个内部类是静态内部类,就比这个好办点了。。
		Test.MyComparator mc=new MyComparator();
		//开始排序,传入比较器对象
		Collections.sort(list,mc);
		//遍历在list中排序之后的HashMap
		for(Iterator<Map.Entry<Integer,String>> it=list.iterator();it.hasNext();)
		{
			System.out.println(it.next());
		}
	}
}

输出:

9=abcde

5=abcd

8=bbb

3=cc

1=a

4=a

在这个程序中,用内部类和用静态内部类没啥太大的区别,就是在调用方法的时候有所区别,显然静态内部类在调用的时候要方便点。。如果是内部类的话,要先创建一个外部类对象,再用这个外部类对象调用内部类构造器,创建内部类对象。

以上就是Comparator接口的主要用法,用来帮助进行HashMap的排序,当然他的老本行还是用来对list进行个性化排序。

为了让小编推荐一下,我就再写个例子,给大家具体演示一下~

  1. import java.util.*;
  2. class Test
  3. {
  4. public static void main(String[] args)
  5. {
  6. List<String> list=new ArrayList<String>();
  7. list.add("z");
  8. list.add("qwe");
  9. list.add("bb");
  10. list.add("abcd");
  11. Collections.sort(list,new Comparator<String>()
  12. {
  13. public int compare(String m,String n)
  14. {
  15. //根据字符串长短排序
  16. return m.length()-n.length();
  17. }
  18. });
  19. //遍历输出排序之后的list
  20. for(Iterator<String> it=list.iterator();it.hasNext();)
  21. {
  22. System.out.println(it.next());
  23. }
  24. }
  25. }
import java.util.*;
class Test
{
	public static void main(String[] args) 
	{
		List<String> list=new ArrayList<String>();
		list.add("z");
		list.add("qwe");
		list.add("bb");
		list.add("abcd");
		Collections.sort(list,new Comparator<String>()
		{
			public int compare(String m,String n)
			{
				//根据字符串长短排序
				return m.length()-n.length();
			}
		});
		//遍历输出排序之后的list
		for(Iterator<String> it=list.iterator();it.hasNext();)
		{
			System.out.println(it.next());
		}
	}
}

输出:

z

bb

qwe

abcd

看完我写的这篇博文,相信大家对hashmap还有list的排序的理解都得到了加深~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(java基础知识)HashMap排序,Comparator接口详解 的相关文章

  • Java线程:volatile关键字

    本文转载至 http lavasoft blog 51cto com 62575 222076 Java线程 volatile关键字 Java 语言包含两种内在的同步机制 同步块 或方法 和 volatile 变量 这两种机制的提出都是为了
  • java并发包:读写锁

    本文转载至 http blog csdn net a910626 article details 51900954 ReadWriteLock是jdk5中提供的读写分离锁 读写分离锁可以有效的帮助减少锁竞争 以提升性能 用锁分离的机制来提升
  • (java基础知识)HashMap排序,Comparator接口详解

    对于List 可以调用Collections工具类的sort 方法 直接进行排序 HashMap 就没这么幸福了 其实 只要了解了Comparator这个接口之后 HashMap的排序也就不难了 无论是根据key 还是根据value排序 这
  • java 清除字符串空格

    JAVA中去掉空格 1 String trim trim 是去掉首尾空格 2 str replace 去掉所有空格 包括首尾 中间 String str hell o String str2 str replaceAll System ou
  • (java 功能篇)java 读取Propety配置文件

    java效果代码 源代码 package com rf test import java io IOException import java io InputStream import java util Properties publi
  • java 线程:概念与原理

    本文转载至 http lavasoft blog 51cto com 62575 99150 一 操作系统中线程和进程的概念 现在的操作系统是多任务操作系统 多线程是实现多任务的一种方式 进程是指一个内存中运行的应用程序 每个进程都有自己独
  • java 阻塞模式与非阻塞模式

    TCP IP 阻塞模式与非阻塞模式 java view plain copy print package concurrentTest import java io BufferedReader import java io IOExcep
  • Java线程:线程栈模型与线程的变量

    本文转载至 http lavasoft blog 51cto com 62575 99152 要理解线程调度的原理 以及线程执行过程 必须理解线程栈模型 线程栈是指某时刻时内存中线程调度的栈信息 当前调用的方法总是位于栈顶 线程栈的内容是随
  • Java线程:新特征-障碍器

    本文转载至 http lavasoft blog 51cto com 62575 222738 Java5中 添加了障碍器类 为了适应一种新的设计需求 比如一个大型的任务 常常需要分配好多子任务去执行 只有当所有子任务都执行完成时候 才能执
  • Java线程:并发协作-死锁

    本文转载至 http lavasoft blog 51cto com 62575 222074 Java线程 并发协作 死锁 线程发生死锁可能性很小 即使看似可能发生死锁的代码 在运行时发生死锁的可能性也是小之又小 发生死锁的原因一般是两个
  • Java 生成随机数全数字方式

    生成9位随机数字 System out println int Math random 9 1 100000000 生成8位随机数字 System out println int Math random 9 1 10000000 生成6位随
  • Java线程:新特征-有返回值的线程

    本文转载至 http lavasoft blog 51cto com 62575 222082 在Java5之前 线程是没有返回值的 常常为了 有 返回值 破费周折 而且代码很不好写 或者干脆绕过这道坎 走别的路了 现在Java终于有可返回
  • Java线程:新特征-信号量

    本文转载至 http lavasoft blog 51cto com 62575 222469 Java线程 新特征 信号量 Java的信号量实际上是一个功能完毕的计数器 对控制一定资源的消费与回收有着很重要的意义 信号量常常用于多线程的代
  • Java线程:线程的调度-守护线程

    本文转载至 http lavasoft blog 51cto com 62575 221845 Java线程 线程的调度 守护线程 守护线程与普通线程写法上基本么啥区别 调用线程对象的方法setDaemon true 则可以将其设置为守护线
  • (java 基础知识) Java 安全套接字--javax.net.ssl

    有关SSL的原理和介绍在网上已经有不少 对于Java下使用keytool生成证书 配置SSL通信的教程也非常多 但如果我们不能够亲自动手做一个SSL Sever和SSL Client 可能就永远也不能深入地理解Java环境下 SSL的通信是
  • java并发包:生产者消费者模式

    本文转载至 http blog csdn net a910626 article details 51900974 生产者消费者模式是一个经典的多线程设计模式 它为多线程间的协作提供了良好的解决方案 在生产者消费者模式中 通常有两类线程 即
  • java并发包:重入锁与Condition条件

    本文转载至 http blog csdn net a910626 article details 51900941 重入锁 这里介绍一下synchronized wait notify方法的替代品 或者说是增强版 重入锁 重入锁是可以完全替
  • (Java 基础知识) Java 正则表达式

    一 概述 正则表达式是Java处理字符串 文本的重要工具 Java对正则表达式的处理集中在以下两个两个类 java util regex Matcher 模式类 用来表示一个编译过的正则表达式 java util regex Pattern
  • Java线程:线程的调度-休眠

    本文转载至 http lavasoft blog 51cto com 62575 221790 Java线程 线程的调度 休眠 Java线程调度是Java多线程的核心 只有良好的调度 才能充分发挥系统的性能 提高程序的执行效率 这里要明确的
  • java并发包:fork/join

    本文转载至 http blog csdn net a910626 article details 51900967 Fork Join框架是Java7提供了的一个用于并行执行任务的框架 是一个把大任务分割成若干个小任务 最终汇总每个小任务结

随机推荐