JAVA高级基础(15)---TreeMap

TreeMap是一个有序的键值对集合,实现基于红黑树,提供自然顺序或自定义Comparator排序。它不依赖key的hashCode和equals方法,而是通过比较器保证键的有序性。虽然查询、插入、删除操作效率低于HashMap,但当需要排序的键值对时,TreeMap是理想选择。TreeMap不允许key为null,且非线程安全,需外部同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TreeMap


TreeMap的原理

TreeMap是一个有序的key-value集合,基于红黑树的 Navigable 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的Comparator 进行排序

红黑树

  1. 根节点是黑色
  2. 每个节点都只能是红色或者黑色
  3. 每个叶节点(NIL节点,空节点)是黑色的。
  4. 如果一个节点是红色的,则它两个子节点都是黑色的,也就是说在一条路径上不能出现两个红色的节点。
  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

    

  • TreeMap存储 Key-Value对时,需要根据Key对key-value对进行排序。TreeMap可以保证所有的Key-Value对处于有序状态
  • TreeMap的Key的排序:TreeSet集合默认会进行排序。因此必须有排序,如果没有就会报类型转换异常。
package org.lanqiao.treemap.demo;

public class Student implements Comparable{
	private String name;
	private Integer age;
	public Student() {
	}
	public Student(String name, Integer age) {
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int compareTo(Object o) {
//		先根据年龄进行排序,如果年龄相同,则使用姓名进行排序
		Student st = (Student)o;
		int res = this.getAge().compareTo(st.getAge());
		if(res == 0 ) {
		res = 	this.getName().compareTo(st.getName());
			
		}
		return res;
	}
	
}
package org.lanqiao.treemap.demo;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {
	public static void main(String[] args) {
		Map map = new TreeMap();
		/*map.put(2, "aa");
		map.put(4, "aa");
		map.put(6, "aa");
		map.put(3, "aa");
		map.put(1, "aa");
		Set set = map.entrySet();
		Iterator iter = set.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			Map.Entry me = (Map.Entry)obj;
			Object key = me.getKey();
			Object value = me.getValue();
			System.out.println(key+"---"+value);
			
		}*/
		/*map.put("b", "张三");
		map.put("d", "张三");
		map.put("e", "张三");
		map.put("c", "张三");
		map.put("a", "张三");
		Set set = map.entrySet();
		Iterator iter = set.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			Map.Entry me = (Map.Entry)obj;
			Object key = me.getKey();
			Object value = me.getValue();
			System.out.println(key+"---"+value);
			
		}*/
		/*Student stu1 = new Student("小强",20);
		Student stu2 = new Student("旺财",18);
		Student stu3 = new Student("买买提",21);
		Student stu4 = new Student("小花",19);
		map.put(2, stu2);
		map.put(1, stu1);
		map.put(4, stu4);
		map.put(3, stu3);
		Set set = map.entrySet();
		Iterator iter = set.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			Map.Entry me = (Map.Entry)obj;
			Object key = me.getKey();
			Object value = me.getValue();
			System.out.println(key+"---"+value);
			
		}*/
		Student stu1 = new Student("小强",20);
		Student stu2 = new Student("旺财",18);
		Student stu3 = new Student("买买提",18);
		Student stu4 = new Student("小花",19);
		map.put(stu2, "bb");
		map.put(stu1, "aa");
		map.put(stu4, "mm");
		map.put(stu3, "cc");
		Set set = map.entrySet();
		Iterator iter = set.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			Map.Entry me = (Map.Entry)obj;
			Object key = me.getKey();
			Object value = me.getValue();
			System.out.println(key+"---"+value);
			
		}
	}
}

 

package org.lanqiao.treemap.demo2;

public class Emp {
	private String name;
	private Integer salary;
	public Emp() {
	}
	public Emp(String name, int salary) {
		this.name = name;
		this.salary = salary;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((salary == null) ? 0 : salary.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Emp other = (Emp) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (salary == null) {
			if (other.salary != null)
				return false;
		} else if (!salary.equals(other.salary))
			return false;
		return true;
	}
	@Override
	public String toString() {
		return "Emp [name=" + name + ", salary=" + salary + "]";
	}
	
	
}
package org.lanqiao.treemap.demo2;

import java.util.Comparator;

public class MyComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		Emp emp1 = (Emp)o1;
		Emp emp2 = (Emp)o2;
		int res = emp1.getSalary().compareTo(emp2.getSalary());
		if(res == 0 ) {
			res = emp1.getName().compareTo(emp2.getName());
			
		}
		return res;
	}

}

 

package org.lanqiao.treemap.demo2;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapComparatorDemo {
	public static void main(String[] args) {
		//创建集合容器
		Map map = new TreeMap(new Comparator() {

			@Override
			public int compare(Object o1, Object o2) {
				Emp emp1 = (Emp)o1;
				Emp emp2 = (Emp)o2;
				int res = emp1.getSalary().compareTo(emp2.getSalary());
				if(res == 0 ) {
					res = emp1.getName().compareTo(emp2.getName());
					
				}
				return res;
			}
		}) ;
		//创建要在容器中保存的对象
		Emp e1 = new Emp("Tom",5000);
		Emp e2 = new Emp("Lilei",8000);
		Emp e3 = new Emp("Mary",3000);
		Emp e4 = new Emp("HanMeiMei",7000);
		//将对象保存到集合中
		map.put(e1, "财务部");
		map.put(e2, "开发部");
		map.put(e3, "行政部");
		//map.put(e4, "开发部");
		map.put(e4, null);
		//遍历集合
		Set set = map.entrySet();
		Iterator iter = set.iterator();
		while(iter.hasNext()) {
			Object obj = iter.next();
			Map.Entry me = (Map.Entry)obj;
			Object key = me.getKey();
			Object value  = me.getValue();
			System.out.println(key +"--"+value);
			
			
		}
		
		
	}
	/*class MyInnerComparator implements Comparator{

		@Override
		public int compare(Object o1, Object o2) {
			Emp emp1 = (Emp)o1;
			Emp emp2 = (Emp)o2;
			int res = emp1.getSalary().compareTo(emp2.getSalary());
			if(res == 0 ) {
				res = emp1.getName().compareTo(emp2.getName());
				
			}
			return res;
		}
		
		
	}*/
}

总结

  1. TreeMap是根据key进行排序的,它的排序和定位需要依赖比较器或覆写Comparable接口,也因此不需要key覆写hashCode方法和equals方法,就可以排除掉重复的key,而HashMap的key则需要通过覆写hashCode方法和equals方法来确保没有重复的key。
  2. TreeMap的查询、插入、删除效率均没有HashMap高,一般只有要对key排序时才使用TreeMap。
  3. TreeMap的key不能为null,而HashMap的key可以为null。
  4. TreeMap不是同步的。如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须 外部同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值