Java——HashMap

Java——HashMap

HashMap
底层: 哈希表存储(数组+链表+红黑树)
特点: 查询,增删效率高,但是无序,存储键值对的值
去重: 根据key做去重,根据key计算桶的位置
扩容:
初始容量: 默认初始用量为16
加载因子: 0.75 当16*0.75达到一个临界点12进行扩容
扩容: 每次扩容原大小的2倍

总结:
如果存储键值对数据–>Map,HashMap
如果存储的单个数据值–>Collection
如果有序,可重复,根据根据索引进行操作 List
大量操作查询 : ArrayList
大量增删操作: LinkedList
如果无序,去重–>Set
HashSet

HashSet–>底层就是用HashMap维护的的key
TreeSet–>底层是由TreeMap维护的key

TreeMap: Map的实现类
底层: 红黑树
特点: 默认升序存储数据
注意: 去重排序都是根据兼职对的key进行计算

import java.util.HashSet;
import java.util.TreeSet;
public class HashMap02 {
	public static void main(String[] args) {
		TreeSet t = new TreeSet();
		t.add("abc");
		t.add("ab");
		t.add("ba");
		t.add("b");
		t.add("a");
		System.out.println(t);
	}
}

简单的HashMap

public class Node {
	int hash; //桶的位置
	Object key;
	Object value;
	Node next; //下个节点的地址
}
public class MyHashMap03 {
	public static void main(String[] args) {
		MyHashMap my = new MyHashMap();
		my.put(10,"aa");
		my.put(20,"bb");
		System.out.println(my.size);
	}
	
}

class MyHashMap{
	Node[] table; //位桶数组
	int size; //存储数据的个数
	
	public MyHashMap() {
		table = new Node[16];
	}

	public void put(Object key,Object value) {
		//1.获取key的hashcode()值,经过hash算法,计算桶的位置
		int hash = hash(key.hashCode(),table.length);
		//新节点
		Node newNode = new Node();
		newNode.hash=hash;
		newNode.key=key;
		newNode.value=value;
		newNode.next=null;
		
		//根据已经计算出桶的位置找到
		Node node = table[hash];
		//如果桶中没有节点数据,newNode节点,作为第一个节点链表头存在,直接放入
		if(node==null) {
			table[hash] = newNode;
			size++;
		}else {
			while(true) {
				//如果key相等,value覆盖
				if(node.key.equals(key)) {
					node.value = value;
					break;
				}
				//判断是存在下一个节点
				if(node.next==null) {
					node.next = newNode;
					size++;
					break;
				}
				node = node.next;
			}
		}
	}
	
	public int size() {
		return this.size;
	}
	
	/**
	 * 根据key的hashcode码计算hash值
	 * @param hashcode key的
	 * @param length   数组的长度
	 * @return 桶的位置
	 */
	public int hash(int hashcode,int length) {
		return hashcode & (length-1);
	}	
}

使用HashMap 和 TreeMap分别存储数据,key为Person类型,value任意类型都可以,进行测试,达到如果Person成员属性都相同,就为一个对象,实现去重

  • 如果TreeMap的排序,要求根据年龄进行升序排序
  • HashMap的key存储自定义引用数据类型: 需要重写equals和hashcode方法
  • TreeMap的key存储为自定义引用数据类型: 需要实现内部|外部比较器
public class MapTest04 {
	public static void main(String[] args) {
		//Map<Person,String> map = new HashMap();
		Map<Person,String> map = new TreeMap((p1,p2)-> ((Person)p1).getAge()-((Person)p2).getAge());
		map.put(new Person("张三",18),"男");
		map.put(new Person("王五",17),"女");
		map.put(new Person("李四",19),"女");
		//根据key做去重,
		map.put(new Person("李四",19),"男");
		
		System.out.println(map);
	}
}
public class MyHashMap03 {
	public static void main(String[] args) {
		MyHashMap my = new MyHashMap();
		my.put(10,"aa");
		my.put(20,"bb");
		my.put(30,"cc");
		System.out.println(my.size);
		System.out.println(my.get(10));
		System.out.println(my.get(20));
		
		System.out.println(my);
	}
	
}

class MyHashMap{
	Node[] table; //位桶数组
	int size; //存储数据的个数
	
	public MyHashMap() {
		table = new Node[16];
	}

	//获取   根据key获取value
	public Object get(Object key) {
		//桶的位置
		int hash = hash(key.hashCode(),table.length);
		
		Node node = table[hash];
		
		while(node!=null) {
			if(node.key.equals(key)) {
				return node.value;
			}
			node = node.next;  //node永远指向新节点
		}
		
		return null;
	}
	
	
	//添加
	public void put(Object key,Object value) {
		//1.获取key的hashcode()值,经过hash算法,计算桶的位置
		int hash = hash(key.hashCode(),table.length);
		//新节点
		Node newNode = new Node();
		newNode.hash=hash;
		newNode.key=key;
		newNode.value=value;
		newNode.next=null;
		
		//根据已经计算出桶的位置找到
		Node node = table[hash];
		//如果桶中没有节点数据,newNode节点,作为第一个节点链表头存在,直接放入
		if(node==null) {
			table[hash] = newNode;
			size++;
		}else {
			while(true) {
				//如果key相等,value覆盖
				if(node.key.equals(key)) {
					node.value = value;
					break;
				}
				//判断是存在下一个节点
				if(node.next==null) {
					node.next = newNode;
					size++;
					break;
				}
				node = node.next;
			}
		}
	}
	
	public int size() {
		return this.size;
	}
	
	/**
	 * 根据key的hashcode码计算hash值
	 * @param hashcode key的
	 * @param length   数组的长度
	 * @return 桶的位置
	 */
	public int hash(int hashcode,int length) {
		return hashcode & (length-1);
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		//循环遍历数组table
		for(Node node:table) {
			// 遍历的是每一个位桶中的链表
			while(node!=null) {
				sb.append(node.key+"="+node.value+",");
				node = node.next;
			}
		}
		return sb.toString().substring(0,sb.length()-1)+"]";
	}
	
}

下一篇,Stream

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值