Map总结

忽略开头:

一个请求包含:请求行+消息头+消息正文
请求行由一行字符串组成的,以CRLF两个符合结尾,CR:回车,用ASCII码13表示,LF:换行,用10表示

请求行:请求方式+请求资源路径+协议版本
eg:GET  /index.html  HTTP/1.1(CRLF)

消息头:由若干行组成,每一行为一个消息头,每个头的格式 : name : value(CRLF)
    在消息头的最后,有一个(CRLF),也就是最后一个消息头末尾跟着两个(CRLF).

消息正文:一个请求中可以不包含消息正文,消息正文是二进制数据,是用户提交给服务器的。

一个响应包含:状态行,响应头,响应正文
状态行:由一行字符串构成(以CRLF结尾):协议版本+状态代码+状态描述
eg:HTTP/1.1 200 OK(CRLF)

响应头:与请求中的消息头一样
响应正文:也是二进制数据。

    
Map接口:特点:多行两列,无序,当我们总是根据一个条件查找一个值的时候,我们就可以考虑到Map结构类型。实际案例:去超市存放包的地方,存了之后会给一个条形码,取包的时候,扫描条形码就可以了。
    Map里的key和value可以是不同的类型。

Map接口的实现类:根据内部数据结构的不同,有多种实现类:
    HashMap:内部为hash表实现的,使用散列算法实现的Map,是当今查询速度最快的数据结构,
                        没有之一,不受数据量的多少影响查询效率。
    TreeMap:内部为排序二叉树实现的
    LinkedHashMap:继承自HashMap,实现了Map接口:允许遍历与put元素时的顺序一致,虽然map是无序的,且顺序于map而言没有什么太大意义,但是如果需要进行有序的话,可以用LinkedHashMap类

    Map接口常用方法
    V put(K key,V value):将Key-Value对存入Map,如果在集合中已经包含该Key,则操作将替换该key所对应的value,返回值为该Key原来
            所对应的Value(如果没有则返回null[这里要注意发生空指针异常])
    
    V get(Object Key):返回key所对应的Value对象, 如果不存在则返回null。
    boolean containsKey(Object key):判断某个key是否在Map中存在(判定的结果是根据equals的结果来的,如果是自定义的                                                                类,必须重写equals(),不然可能会影响结果)
    Map提供了三种遍历方式:
    Set<K> keySet():遍历所有的key,因为所有的key是不可以重复的,故返回的Set集合
    Set<Entry<K,V>> entrySet():将当前Map中每一组key-value对封装为一个Entry对象并存入一个Set集合后返回。
                                                 Entry是Map的一个内部接口,其实现类的每一个实例应用于表示当前Map的一组键值对。
    Collection<V> values():遍历所有的value返回的是一个Collection,不是Set,因为value是可以重复的。
    
关于Map是查找效率最快的问题?
    为什么是最快的:因为它根据key而直接算出元素的下标(相当于知道酒店的房牌号,一下就能找到)
    一对键值对在存入的时候会调用key的hashCode()检索出酒店的房间,选择要放的位置。


    正常情况下,一个格子(一个房间)只有一对键值对(两个属性:key,value),但是如果两个key的hashcode值相等,那么他俩就放在了一起,就产生了链表,查询效率就会降低
    格子里就会有三个属性:key,value,entry next:保存指向它的下一个的引用地址

    怎么避免hashcode()相等?(怎么避免产生链表)
    自己定义的类一定要重写hashcode(),不能只重写equals(),因为这两个方法都是Object的,如果只重写equals(),会打破hashcode()里面的定义。
    
    对equals()和hashcode()重写的规则:
    1.成对重写:两个一起被重写
    2.一致性
        equals()为true时,hashcode()一定为 true;
        hashcode()为true时,equals()不一定为true;
        故要保证,hashcode()值相等时,equals()也为true
        当hashcode()值相等,equals()不相等时会产生链表,影响效率。
    3.稳定性
        当参与equals()比较的属相没有发生改变的情况下,多次调用hashcode()返回的数字应当保持不变

重写equals()和hashcode():

class Demo{
	private int x;
	private int y;
	
	public int hashCode(){
		final int prime = 31;
		int result = 1;//1和31都不重要,重要的是prime是final,不可变
		result = prime*result+x;
		result = prime*result+y;
		return result;
	} 
}

class Demo2{
	private String name;
	private String pwd;
	
	public int hashcode(){
		final int prime = 31;
		int result = (name==null)?0:name.hashCode();
		result = prime*result +((pwd==null)?0:pwd.hashCode());
		return result;
	}
	
	public boolean equals(Object obj){
		if(this==obj){
			return true;
		}
		if(obj==null){
			return false;
		}
		if(obj.getClass()!=this.getClass()){
			return false;
		}
		Demo2 demo2 = (Demo2)obj;
		if(demo2.name.equals(this.name)&&(demo2.pwd.equals(this.pwd))){
			return true;
		}else{
			return false;
		}
	}
}

装载因子及HashMap优化:
    capacity:容量,hash表里桶的数量,也就是善良数组大小
    Initial capacity:初始容量,创建hash表时,初始bucket(桶)的数量,默认为16;
    Size:大小,当前善良表中存储数据的数量
    Load factor:加载因子,默认值为0.75,当向散列表增加数据时如果size/capacity的值大于Load factor时发生扩容并且重新散列。
    性能优化:加载因子比较小时,散列表查找性能会提高,同时也浪费了散列桶空间容量。
    为什么加载因子是0.75而不是其他的值:0.75是性能和空间相对平衡结果。因为每次扩容都要把里面的所有的元素重新调用hashcode()分配空间。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值