【JAVASE】HashMap与TreeMap的排序与存储对象的区别

前言

我们知道,HashMap不会对键进行排序,而TreeMap会对键进行排序,当然这两者还有很多其他的区别,本文为了保持主题一致,只考虑排序的影响因素,当然本文实际上没有经过其他参考资料验证,也是在自己使用HashMap与TreeMap时所产生的疑惑,并且记录下来,比如当两者的key为integer时,两者都会对键进行排序,而对字符串、自定义类型却会体现不同。而网上探讨角度过于深奥,也许原因会与深层的机制有关,本人也不是很了解就不献丑了,在此仅演示一下两者的实例。

当然若有错误欢迎批评指正。

键为整形(Integer)

HashMap自动排序的情况

当hashmap的键的最大值与第二大的键相差小于16时(不包括16),hashmap会自动排序

package Lab7;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
// Treemap会对键进行排序,而HashMap不会
public class Lab7_3 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		HashMap<Integer, String>mp=new HashMap<Integer,String>();		
		mp.put(11, "bna");
		mp.put(2, "apple");
		mp.put(1, "banana");
		mp.put(3, "chel");
		mp.put(5, "d");
		mp.put(4, "e");
		mp.put(7, "f");
		mp.put(6, "g");
		mp.put(8, "h");
		mp.put(10, "l");
		mp.put(9, "o");
		System.out.println(mp);
		Set<Integer>set=mp.keySet();
		Iterator<Integer>it=set.iterator();
		for (Integer i : mp.keySet()) {
			System.out.println("key: "+i+" value:"+mp.get(i));
		}
		TreeMap<Integer, String>MP=new TreeMap<Integer,String>();
		MP.put(11, "bna");
		MP.put(2, "apple");
		MP.put(1, "banana");
		MP.put(3, "chel");
		MP.put(5, "d");
		MP.put(4, "e");
		MP.put(7, "f");
		MP.put(6, "g");
		MP.put(8, "h");
		MP.put(10, "l");
		MP.put(9, "o");	
		System.out.println(MP);
		for (Integer i : MP.keySet()) {
			System.out.println("key: "+i+" value:"+MP.get(i));
		}
		
}

输出

{1=banana, 2=apple, 3=chel, 4=e, 5=d, 6=g, 7=f, 8=h, 9=o, 10=l, 11=bna}
key: 1 value:banana
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 7 value:f
key: 8 value:h
key: 9 value:o
key: 10 value:l
key: 11 value:bna
{1=banana, 2=apple, 3=chel, 4=e, 5=d, 6=g, 7=f, 8=h, 9=o, 10=l, 11=bna}
key: 1 value:banana
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 7 value:f
key: 8 value:h
key: 9 value:o
key: 10 value:l
key: 11 value:bna

可以看到,对于键为整形的映射关系,HashMap与TreeMap都会进行排序,这一点是众多教材都没有指出来的特殊情况,这一点也是我在实践中遇到的问题。

HashMap不会自动排序的情况

当hashmap键的最大值与第二大的键大于等于16时,hashmap不对该键进行排序,而其他小于16的键仍然会自动排序

package Lab6;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
// Treemap会对键进行排序,而HashMap不会
public class Lab6_1 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		HashMap<Integer, String>mp=new HashMap<Integer,String>();		
		mp.put(11, "bna");
		mp.put(2, "apple");
		mp.put(1, "banana");
		mp.put(3, "chel");
		mp.put(16, "ld");
		mp.put(5, "d");
		mp.put(4, "e");
		mp.put(15, "we");
		mp.put(17, "f");
		mp.put(6, "g");
		mp.put(32, "os");
		mp.put(8, "h");
		mp.put(10, "l");
		mp.put(9, "o");
		mp.put(12, "ll");
		mp.put(13, "oo");
		mp.put(14, "lsd");
		
		
		
		System.out.println(mp);
		Set<Integer>set=mp.keySet();
		Iterator<Integer>it=set.iterator();
		for (Integer i : mp.keySet()) {
			System.out.println("key: "+i+" value:"+mp.get(i));
		}
		TreeMap<Integer, String>MP=new TreeMap<Integer,String>();
		MP.put(11, "bna");
		MP.put(2, "apple");
		MP.put(1, "banana");
		MP.put(3, "chel");
		MP.put(16, "ld");
		MP.put(5, "d");
		MP.put(4, "e");
		MP.put(15, "we");
		MP.put(17, "f");
		MP.put(6, "g");
		MP.put(32, "os");
		MP.put(8, "h");
		MP.put(10, "l");
		MP.put(9, "o");
		MP.put(12, "ll");
		MP.put(13, "oo");
		MP.put(14, "lsd");
		
		
		System.out.println(MP);
		for (Integer i : MP.keySet()) {
			System.out.println("key: "+i+" value:"+MP.get(i));
		}
		
}
}

输出:

{32=os, 1=banana, 2=apple, 3=chel, 4=e, 5=d, 6=g, 8=h, 9=o, 10=l, 11=bna, 12=ll, 13=oo, 14=lsd, 15=we, 16=ld, 17=f}
key: 32 value:os
key: 1 value:banana
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 8 value:h
key: 9 value:o
key: 10 value:l
key: 11 value:bna
key: 12 value:ll
key: 13 value:oo
key: 14 value:lsd
key: 15 value:we
key: 16 value:ld
key: 17 value:f
{1=banana, 2=apple, 3=chel, 4=e, 5=d, 6=g, 8=h, 9=o, 10=l, 11=bna, 12=ll, 13=oo, 14=lsd, 15=we, 16=ld, 17=f, 32=os}
key: 1 value:banana
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 8 value:h
key: 9 value:o
key: 10 value:l
key: 11 value:bna
key: 12 value:ll
key: 13 value:oo
key: 14 value:lsd
key: 15 value:we
key: 16 value:ld
key: 17 value:f
key: 32 value:os

键为字符串

package Lab7;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
// Treemap会对键进行排序,而HashMap不会
public class Lab7_3 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		HashMap<String, String>mp=new HashMap<>();		
		mp.put("11", "bna");
		mp.put("2", "apple");
		mp.put("1", "banana");
		mp.put("3", "chel");
		mp.put("5", "d");
		mp.put("4", "e");
		mp.put("7", "f");
		mp.put("6", "g");
		mp.put("8", "h");
		mp.put("10", "l");
		mp.put("9", "o");
		System.out.println(mp);
		Set<String>set=mp.keySet();
		Iterator<String>it=set.iterator();
		for (String i : mp.keySet()) {
			System.out.println("key: "+i+" value:"+mp.get(i));
		}
		TreeMap<String, String>MP=new TreeMap<String,String>();
		MP.put("11", "bna");
		MP.put("2", "apple");
		MP.put("1", "banana");
		MP.put("3", "chel");
		MP.put("5", "d");
		MP.put("4", "e");
		MP.put("7", "f");
		MP.put("6", "g");
		MP.put("8", "h");
		MP.put("10", "l");
		MP.put("9", "o");
		System.out.println(MP);
		for (String i : MP.keySet()) {
			System.out.println("key: "+i+" value:"+MP.get(i));
		}
}

输出

{11=bna, 1=banana, 2=apple, 3=chel, 4=e, 5=d, 6=g, 7=f, 8=h, 9=o, 10=l}
key: 11 value:bna
key: 1 value:banana
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 7 value:f
key: 8 value:h
key: 9 value:o
key: 10 value:l
{1=banana, 10=l, 11=bna, 2=apple, 3=chel, 4=e, 5=d, 6=g, 7=f, 8=h, 9=o}
key: 1 value:banana
key: 10 value:l
key: 11 value:bna
key: 2 value:apple
key: 3 value:chel
key: 4 value:e
key: 5 value:d
key: 6 value:g
key: 7 value:f
key: 8 value:h
key: 9 value:o

可以看到,HashMap没有进行排序,而TreeMap会对字符串的首字符进行排序,如"1",“10”,“11"首字符都为"1”,根据ASCII码都小于"2"

为了更好的说明,下面的例子将键改为字母进行比较:

package Lab7;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
// Treemap会对键进行排序,而HashMap不会
public class Lab7_3 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		HashMap<String, String>mp=new HashMap<>();		
		mp.put("a", "bna");
		mp.put("b", "apple");
		mp.put("e", "banana");
		mp.put("r3", "chel");
		mp.put("t5", "d");
		mp.put("s4", "e");
		mp.put("fd7", "f");
		mp.put("jf6", "g");
		mp.put("l8", "h");
		mp.put("o10", "l");
		mp.put("p9", "o");
		System.out.println(mp);
		Set<String>set=mp.keySet();
		Iterator<String>it=set.iterator();
		for (String i : mp.keySet()) {
			System.out.println("key: "+i+" value:"+mp.get(i));
		}
		TreeMap<String, String>MP=new TreeMap<String,String>();
		MP.put("a", "bna");
		MP.put("b", "apple");
		MP.put("e", "banana");
		MP.put("r3", "chel");
		MP.put("t5", "d");
		MP.put("s4", "e");
		MP.put("fd7", "f");
		MP.put("jf6", "g");
		MP.put("l8", "h");
		MP.put("o10", "l");
		MP.put("p9", "o");
		System.out.println(MP);
		for (String i : MP.keySet()) {
			System.out.println("key: "+i+" value:"+MP.get(i));
		}
		
}

输出

{a=bna, r3=chel, t5=d, s4=e, b=apple, e=banana, fd7=f, p9=o, jf6=g, l8=h, o10=l}
key: a value:bna
key: r3 value:chel
key: t5 value:d
key: s4 value:e
key: b value:apple
key: e value:banana
key: fd7 value:f
key: p9 value:o
key: jf6 value:g
key: l8 value:h
key: o10 value:l
{a=bna, b=apple, e=banana, fd7=f, jf6=g, l8=h, o10=l, p9=o, r3=chel, s4=e, t5=d}
key: a value:bna
key: b value:apple
key: e value:banana
key: fd7 value:f
key: jf6 value:g
key: l8 value:h
key: o10 value:l
key: p9 value:o
key: r3 value:chel
key: s4 value:e
key: t5 value:d

可以看到,对于键为字符串的映射关系,TreeMap会对其进行ASCII码的比较进行排序,而HashMap则不会。

键为自定义类型

注意代码中对自定义类型重载了比较运算符,并重载了输出


package Lab7;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
// Treemap会对键进行排序,而HashMap不会
public class Lab7_3 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

		HashMap<student, Integer>lovesHashMap=new HashMap<>();
		lovesHashMap.put(new student("李白", 1), 2);
		lovesHashMap.put(new student("王安石", 2), 3);
		lovesHashMap.put(new student("格斯", 3), 4);
		lovesHashMap.put(new student("嘎哈", 4), 5);
		lovesHashMap.put(new student("李白1", 5), 6);
		lovesHashMap.put(new student("李白2", 6), 7);
		lovesHashMap.put(new student("李白3", 7), 8);
		lovesHashMap.put(new student("李白4", 8), 9);
		lovesHashMap.put(new student("李白5", 9), 10);
		for (student stu : lovesHashMap.keySet()) {
			System.out.println(stu);
		}
		System.out.println();
		TreeMap<student, Integer>lmp=new TreeMap<>();
		lmp.put(new student("李白", 1), 2);
		lmp.put(new student("王安石", 2), 3);
		lmp.put(new student("格斯", 3), 4);
		lmp.put(new student("嘎哈", 4), 5);
		lmp.put(new student("李白1", 5), 6);
		lmp.put(new student("李白2", 6), 7);
		lmp.put(new student("李白3", 7), 8);
		lmp.put(new student("李白4", 8), 9);
		lmp.put(new student("李白5", 9), 10);
		for (student stu : lmp.keySet()) {
			System.out.println(stu);
		}
	}

}
class student implements Comparable<student>{
	public student(String nameString,int id) {
		// TODO 自动生成的构造函数存根
		this.nameString=nameString;
		this.id=id;
	}
	private String nameString;
	private int id;
	@Override
	public int compareTo(student arg0) {
		// TODO 自动生成的方法存根
		if(this.id>arg0.id)return 1;
		else if(this.id<arg0.id)return -1;
		return 0;
	}
	@Override
	public String toString() {
		// TODO 自动生成的方法存根
		return "名字:"+nameString+"      学号为:"+id;
	}
}

输出

名字:李白      学号为:1
名字:嘎哈      学号为:4
名字:李白1      学号为:5
名字:格斯      学号为:3
名字:李白4      学号为:8
名字:李白3      学号为:7
名字:王安石      学号为:2
名字:李白5      学号为:9
名字:李白2      学号为:6

名字:李白      学号为:1
名字:王安石      学号为:2
名字:格斯      学号为:3
名字:嘎哈      学号为:4
名字:李白1      学号为:5
名字:李白2      学号为:6
名字:李白3      学号为:7
名字:李白4      学号为:8
名字:李白5      学号为:9

可以看到TreeMap的键进行了排序,而HashMap的并没有

总结

  1. 对于键为integer,HashMap与TreeMap都会进行排序
  2. 对于键为String,自定义类型,TreeMap会对键进行排序,而HashMap则不会
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LenckCuak

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值