双例集合

本文详细介绍了Java中的Map接口及其子类HashMap和TreeMap的使用,包括Map与Collection的区别、HashMap的添加、获取、并集操作、删除及键值判断,以及TreeMap的插入规则和比较器应用。还涵盖了底层源码分析和关键数据结构原理。
摘要由CSDN通过智能技术生成

双例集合

一、Map接口
1.Map接口的特点
在这里插入图片描述
2.Map与Collection的区别
在这里插入图片描述

3.Map接口的常用方法
在这里插入图片描述
其他的方法可自行通过api文档查询

二、HashMap容器类
在这里插入图片描述

/**
 * 测试HashMap的相关方法
 */
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class HashMap_Test {
	public static void main(String[] args) {
		//实例化HashMap容器
		Map<String, String> m1=new HashMap<>();
		
		System.out.println("--------添加元素----------");
		//添加元素
		/**在put方法中,如果Map中不存在添加的key值,则返回NULL;
		如果存在该key值,则原来的value值被新的value值替换,且返回原来的value值
		*/
		System.out.println(m1.put("a", "A"));//输出null
		System.out.println(m1.put("a", "A1"));//输出A,且在HashMap中原来的A被A1代替
		m1.put("b", "B");//返回null
		m1.put("c", "C");
		m1.put("d", "D");
		
		System.out.println("----------获取元素--------------");
		//通过key值获取元素(value)
		System.out.println(m1.get("a"));//需在知道key的情况下才能获取对应的value值,获取所有value值时不方便
		
		System.out.println("------------------------");
		//获取HashMap中所有元素可以通过keySet方法和get方法一起完成
		Set<String> keys=m1.keySet();//获取所有的key存在Set容器中
		
		for(String key:keys){
			String value=m1.get(key);
			System.out.println(key+"-----"+value);
		}
		
		System.out.println("------------------------");
		//通过entrySet方法获取Map.Entry类型获取元素
		//Map容器内有个Entry接口
		Set<Map.Entry<String, String>>  entrySet = m1.entrySet();
	
		for(Map.Entry<String, String> entry:entrySet){
			System.out.println("key:"+entry.getKey()+"---------"+"value:"+entry.getValue());
		}
		
		System.out.println("------------并集操作---------------");
		Map<String, String> m2=new HashMap<>();
		m2.put("e", "E");
		m2.put("d", "D");
		m2.put("b", "B1");
		
		//并集时有相同的key值,m1(被并集操作的map容器)中的value值会把m2(当前的map容器)的value值给覆盖掉
		m2.putAll(m1);
		
		Set<String> key2=m2.keySet();
		for(String key:key2){
			System.out.println("key="+key+"-----------"+"value="+m2.get(key));
		}
		
		System.out.println("-----------删除元素-------------");
		System.out.println(m2.remove("a"));//返回被删除元素的value值
		Set<String> key3=m2.keySet();
		for(String key:key3){
			System.out.println("key "+key+" value "+m2.get(key));
		}
		
		System.out.println("---判断key与value是否存在-----");
		System.out.println(m1.containsKey("a"));
		System.out.println(m2.containsKey("a"));
		
		System.out.println(m1.containsValue("A1"));
		System.out.println(m2.containsValue("A1"));
	}
}

三、HashMap的底层源码分析
1.底层存储介绍
在这里插入图片描述
在这里插入图片描述
2.HashMap的成员变量
在这里插入图片描述
在这里插入图片描述

DEFAULT_INITIAL_CAPACITY:默认数组部分的初始容量16,必须是2的次幂
在这里插入图片描述
MAXIMUM_CAPACITY:数组部分的最大容量2的30次方
在这里插入图片描述
DEFAULT_LOAD_FACTOR:负载因子,数组扩容的负载因子,当数组容量达到75%的时候(即16*0.75=12),开始扩容
在这里插入图片描述
TREEIFY_THRESHOLD : 当树的容量达到8时,转化为红黑树,链表转红黑树的一个阈值
在这里插入图片描述
UNTREEIFY_THRESHOLD : 红黑树转链表的一个阈值在这里插入图片描述
MIN_TREEIFY_CAPACITY:当数组容量达到64时才进行链表与红黑树的转化
在这里插入图片描述
size:记录Map中的键值对的数量
在这里插入图片描述
table:存放链表和红黑树的数组
在这里插入图片描述

3.HashMap中存储元素的结点类型

链表的结点类Node
在这里插入图片描述

红黑树的结点类TreeNode
在这里插入图片描述
在这里插入图片描述
TreeNode类继承了Node类,以便于在table(Node类型的数组)中存放链表结点和红黑树结点
在这里插入图片描述
4.数组初始化
在这里插入图片描述
在这里插入图片描述
5.计算Hash值

  1. 获得key对象的hashcode,首先调用key 对象的hashcode()方法,获得key 的 hashcode值。
  2. 根据hashcode计算出hash值(要求在[0,数组长度-1]区间)hashcode是一个整数,我们需要将它转化成[O,数组长度-1]的范围。我们要 求转化后的hash 值尽量均匀地分布在[0,数组长度-1]这个区间,减少"hash冲突"
    在这里插入图片描述
    在这里插入图片描述
    Hash方法:高16位于低16位的异或运算
    在这里插入图片描述
    在这里插入图片描述
    6.添加元素
    在这里插入图片描述

7.数组扩容
在这里插入图片描述
在这里插入图片描述

四、TreeMap容器类
在这里插入图片描述
TreeMap中添加元素时必须对key实现比较规则,否则会报错,TreeMap无法将一个没有比较规则的key添加进来

  • 元素自身实现比较规则
  • 通过比较器实现比较规则
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMap_Test {
	public static void main(String[] args) {
		//实例化TreeMap
		System.out.println("------通过元素自身实现比较规则------");
		Map<Users, String> map=new TreeMap<>();
		Users u1=new Users("the Mutents", 21);
		Users u2=new Users("小白", 20);
		Users u3=new Users("李明", 20);
		
		map.put(u1, "男");
		map.put(u2, "女");
		map.put(u3, "男");
		
		Set<Users> keys=map.keySet();
		for(Users key:keys){
			System.out.println("key: "+key+" value: "+map.get(key));
		}
		
		
		System.out.println("-------通过比较器实现比较规则--------");
		Map<Student, String> map2=new TreeMap<>(new StudentComparator());
		Student s1=new Student("the Mutents", 21);
		Student s2=new Student("小白", 20);
		Student s3=new Student("李华", 20);
		
		map2.put(s1, "男");
		map2.put(s2, "女");
		map2.put(s3, "男");
		
		Set<Student> stu=map2.keySet();
		
		for(Student key:stu){
			System.out.println("key: "+key+" value: "+map2.get(key));
		}	
	}
}

public class Users implements Comparable<Users>{

	private String username;
	private int userage;
	
	
	public Users() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Users(String username, int userage) {
		super();
		this.username = username;
		this.userage = userage;
	}
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public int getUserage() {
		return userage;
	}
	public void setUserage(int userage) {
		this.userage = userage;
	}

	@Override
	public String toString() {
		return "Users [username=" + username + ", userage=" + userage + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + userage;
		result = prime * result + ((username == null) ? 0 : username.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;
		Users other = (Users) obj;
		if (userage != other.userage)
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
	
	//定义比较规则
	//返回值为正数:大,返回值为负数:小,返回值为0:相等
	//定义一个按年龄比较的比较规则,由小到大
	@Override
	public int compareTo(Users o) {
		if(this.userage>o.getUserage()){
			return 1;
		}
		if(this.userage==o.getUserage()){
			return  this.username.compareTo(o.getUsername());
		}
		return -1;
	}
	
	
}
//比较器
import java.util.Comparator;

public class StudentComparator  implements Comparator<Student> {

	//定义比较规则
	@Override
	public int compare(Student o1, Student o2) {
		if(o1.getAge()>o2.getAge()){
			return 1;
		}
		if(o1.getAge()==o2.getAge()){
			return o1.getName().compareTo(o2.getName());
		}
		return -1;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

The Mutents

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

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

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

打赏作者

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

抵扣说明:

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

余额充值