什么是Hashmap及集合全家桶

本文讲解了集合基础、equals与hashCode重写在ArrayList、HashSet和TreeSet中的应用,以及HashMap的put、get原理及关键参数。重点剖析HashMap的底层实现,包括哈希函数、负载因子和数据结构转换。
摘要由CSDN通过智能技术生成


前言

hashmap作为面试重点下面让我们进行了解
在学Hashmap前我们先来复习一下什么是集合

一、什么是集合?

集合:长度可以动态的增减,可以存放不同类型的元素,java中,所有的集合都放在Java.util包下
Collection 体系:

	Collection (接口)  ==> List  接口  ==> ArrayList
																		 ==> LinkedList
																		 ==> Vector ==>Stack (类)
																		        
			
										 ==> Set 接口 ==> HashSet
										 							==> TreeSet
										 							
										 ==> Queue  接口

List和set的区别(干货)
list有序 按照对象计入的顺序保存,可重复,允许多个null对象,可以使用iterrater取出元素 也可以用get方法.
set无序,不可重复,最多允许一个null元素对象,取元素只能用iterater.

二、重写equals ,hash,自定义compare

1.ArrayList重写equals

equals比较是堆中内存对象的地址

List集合,进行元素相等比较的时候用的是 元素的 equals 方法,如果在List集合中存放自定义对象,最好重写自定义对象的 equals() 方法

代码如下(示例):

//比较对象定位Cat   List list=new ArrayList();
       //  list.add(new Cat(1,"tom","中国","黑"));
public boolean equals(Object obj){
           if(this==obj)
           return true;
           if(!(obj instanceof Cat)){
           return fasle;
           Cat cat = (Cat) obj;
           if(this.name.equals(cat.name) && this.age==cat.age && this.address.equals(cat.address) &&this.color.equals(cat.color)) {
						return true;	
					}
					else {
						return false;
					}
}

2.HashSet重写equals和hashCode

以前我们学的List集合,进行相等比较的时候,用的是元素的 equals()方法
HashSet集合,进行相等比较的时候, 它是先比较元素的 hashCode() 方法的返回值。如果返回值相同,再调用equals() 进行比较

代码如下(示例):

 //重写hashCode()    Set set=new HashSet();
					//set .add(new Cat(2,"tom"));
				public int hashCode() {
					/*
					int result=17;
					result=31*result+name.hashCode();
					result=31*result+age;
					return result;  */
					//因为 31* i可以被jvm优化成 i<<5-i
					
					return Objects.hash(age,name);	
				}
//重写equals
                public boolean equals(Object o) {
					if(this==o) 
						return true;
					if(!(o instanceof Cat))
						return false;
					
					Cat c=(Cat)o;
			    if(this.age==c.age&&this.name.equals(c.name)) 
						return true;
					
					return false;
				}	

3.TreeSet自定义类型进行排序

//例子 使用匿名内部类/*TreeSet t=new TreeSet(new StrLenComp() ) ;
					t.add("this");
					t.add("aog");
					t.add("vvvvv");
					t.add("buffer");
					t.add("ship");
					t.add("longlong");
					t.add("wha");
					t.add("ha");*/
			   	TreeSet t=new TreeSet(new Comparator() {
							public int compare(Object o1, Object o2) {
								String s1=(String)o1;
								String s2=(String)o2;
								
								if(s1.length()>s2.length()) {
									return 1;
								}
								else {
									return -1;
								}
							}
							
						} ) ;

什么是HashMap

众所周知,HashMap是一个用于存储Key-Value键值对的集合,每个简直对也叫做Entry。这些个简直对(entry)分散存储在一个数组当中,这个数组就是HashMap的主干。
HashMap数组每个元素的初始值都是Null.

1.put方法的原理

调用Put方法的时候发生了什么呢?
比如调用hashMap.put(“luanma”,0),插入一个Key为“luanma” 的元素,这是我们需要利用一个哈希函数来确定Entry的插入位置(index).
注意:HashMap数组每个元素不止是一个Entry对象,当映射到冲突的数组位置时,运用链表头插法,代替原来的Entry之前的变成当前Entry的下一个节点

2.get方法原理

把输入的Key做一次Hash映射,index = Hash(“luanma”)得到对应的index:比配Key值,返回Value。HashMap的发明者认为,后插入的Entry被查找的可能性更大。1.7为头插发,1.8为尾插法

3.HashMap的相关说明

    1) 默认初始容量
		    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //16 , 必须是2的整数次方(以后扩容的时候也是这样)
		    
		2) 最大容量
		    static final int MAXIMUM_CAPACITY = 1 << 30; 
		    
		3) 默认装载因子
		    static final float DEFAULT_LOAD_FACTOR = 0.75f   //值可以大于1 
		        这个值越小,操作的速度越快(是因为产生hash冲突的可能性降低了,省去很多链表操作),但浪费空间
		        这个值大,效果和上面相同 , 速度会慢 (装的满,产生hash 冲突的可能性就高), 但节省空间
		        
		4) static final int TREEIFY_THRESHOLD = 8; //链表变成红黑树的临界值,链表的长度到达这个值以后,就成红黑树 
		
		5) static final int UNTREEIFY_THRESHOLD = 6;  //当数据从红黑树中移除,数据减小到这个值的时候,还原成链表
		
		6) static final int MIN_TREEIFY_CAPACITY = 64; //当链表转成红黑树之前,还要进行一次判断,看看map集合中的数据总量是不是到达这个值了,到了才转换,不到不转换
		                                               // 防止在哈希表建立初期,多个键正好放到了一个节点上的情况
		                                               7) transient int size; //装的键值对的个数
  
        8) transient Node<K,V>[] table;  //哈希桶
  
        9) final float loadFactor; //用户指定的装载因子
  
        10) int threshold; // hashMap 进行扩容临界值

重要方法
1) 哈希函数 ,又叫扰动函数 ,也叫散列值优化函数 ,它的目的是降底 hash值 冲突的可能性

	    static final int hash(Object key) {
	    		int h;
	    		if(key == null){
	    				return 0;
	    		}
	    		else{
	    		 	h = key.hashCode()
	    		 	h = h^(h >>> 16);   //移位以后,进行异或,会让原来的数的高,低位都参与运算,让结果更混乱
	    		}
	    		
	    		return h;		
	    }
	     2) 根据哈希值, 计算元素在哈希桶中的索引  
	     //h 哈希值
	     //length 是哈希桶的长度,它总是2的n次方
	     public int indexFor(int h, int length){
	     		return h&(length-1);   //这个写法,相当于 h % length 求余   (前题,是length 必须是2的整数次方)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值