首页 > 编程知识 正文

java io面试题,java三大特性面试回答

时间:2023-05-06 10:23:05 阅读:15478 作者:3035

目录HashMap简介快速入门技术本质数据结构:数组、链表算法: xhdhxc算法(散列) xhdhxc算法和xhdhxc碰撞xhdhxc算法简介xhdhxc碰撞) xhdhxc碰撞) xhdhxc碰撞如何通过链表的数据结构解决手写hashmap的实现? 为什么要在jdk8之后用红黑树实现? 用纯数组链表实现问题红黑树简介红黑树结构特点红黑树与链表性能比较为什么jdk1.8中红黑树阈值设置为8?

混沌图概述

简而言之,hashmap是用于存储key-value键-值对的数据结构。

快速启动存储: put () )

查询: get () )。

技术的本质编程的本质=数据结构算法

hashmap在jdk7中使用的数据结构是数组链表

hashmap在jdk8上使用的数据结构是数组链表红黑树

算法: xhdhxc算法

数据结构:数组、链表

3358www.Sina.com/:使用连续存储单元存储数据特征:查询数组(o ) 1,插入o(n ) ) jdk中的http://www.Sina.com/

3358www.Sina.com/是物理存储器单元上的非连续、非连续存储器结构的特征。查询快,插入删除慢(插入删除时间复杂度o(1),查找时间复杂度o(1 ) ) jdk中的3358www.Sina.coom

xhdhxc算法和xhdhxc碰撞xhdhxc算法概述xhdhxc算法(也称为散列)将任意长度的值(key )由散列算法转换为固定长度的key )地址,并从该地址访问

通过将键码映射到表中的位置来访问记录,从而减少搜索时间。

Hashcode :根据字符串计算出他的ascii码,进行mod (建模),计算出xhdhxc表中的下标,将建模的值n作为数组的长度

下图显示字符串“lies”的xhdhxc运算为429 % 10=9。 假设n为10

将字符串“lies”保存在数组下标为9的位置

思考:为什么要进行模具操作?

答:为了节约排列空间

xhdhxc碰撞(xhdhxc碰撞)思考:上述模具操作会带来什么问题?

取不同key的xhdhxc值后,得到相同的计算结果,xhdhxc可能发生冲突

什么是xhdhxc冲突?

如上图所示,“lies”和“foes”两个不同的密钥可以存储在hashmap中数组下标为9的位置。 此时,会发生xhdhxc竞争。

在链表数据结构中解决链表头插方法的方法是:将最新计算出的xhdhxc值存储在对应的数组下标中,判断数组对应的索引是否为空,如果不为空则原样存储,如果不为空则将最新节点的next存储在原始索引中

手写实现hashmap定义接口规范,稍后创建类并具体实现

package com.bnuz.hashmap; 公共接口标记,v{vput(kk,vvv ); vget(kk ); int size (; 接口输入,V{ K getKey (; V getValue (; }} hashmap实现的中心方法是put (和get )

链表查询在这里采用递归的写法

package com.bnuz.hashmap; 公共类hashmapk,V implements MapK,V { private EntryK,V table[]=null; int size=0; public hashmap ((this.table=newentry [ 16 ]; }/*计算hash算法传递的key的xhdhxc值并取膜后,找到索引下标数组为当前下标的对象,判断当前对象是否为空,否则为xhdhxc碰撞(碰撞) next链接@overridepublicvput,v ) )的EntryK,V entry=table[index]; if(entry==null ) (/无冲突,直接存储表[ index ]=new entry

lt;>(k,v,index,null);//赋值给当前下标结点 size++; }else{ //出现xhdhxc冲突(碰撞) table[index] = new Entry<>(k,v,index,entry);//头插链表 } return table[index].getValue(); }//计算下标,xhdhxc值取膜16 private int hash(K k) { int index = k.hashCode() % 16; return index>=0?index:-index;//由于数组下标由0开始,需返回正数 } /* * 通过传入的key 进行hash计算 * 找到index下标数组对象 * 判断当前index下标对象是否为空 若为不为空 * 判断是否相等 若不相等 * 则判断index.next是否为空 若不为空 * 再判断是否相等 直到找到相等或为next为null 返回 * */ @Override public V get(K k) { if (size==0){ return null; } int index = hash(k); Entry<K,V> entry = findValue(table[index],k); return entry==null?null:entry.getValue(); } //k是期望查询的key值 entry为取出下标的结点 private Entry<K,V> findValue(Entry<K,V> entry, K k) { if(k.equals(entry.getKey())||k==entry.getKey()){ return entry; }else { if (entry.next!=null){ return findValue(entry.next,k); } } return null; } @Override public int size() { return size; } class Entry<K,V> implements Map.Entry<K,V>{ K k;V v; //带参数的构造器 public Entry(K k, V v, int hash, Entry<K, V> next) { this.k = k; this.v = v; this.hash = hash; this.next = next; } int hash;Entry<K,V> next; @Override public K getKey() { return k; } @Override public V getValue() { return v; } }}

测试代码:

package com.bnuz.hashmap;public class test { public static void main(String[] args) { Map<String,String> map = new HashMap<>(); map.put("B","百度"); map.put("A","阿里"); map.put("T","腾讯"); System.out.println(map.get("A")); System.out.println(map.get("T")); }}

运行结果:

为什么要在jdk8之后用红黑树来实现?

java8 HashMap结构

用纯数组+链表实现带来的问题


前面提到过链表查询慢的特点,以上图为例,出现大量的xhdhxc碰撞,如果我们要查最后一个结点,将会给性能带来很大的影响

红黑树简介

红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能

红黑树的结构特点

六个字总结:左中右 小中大

红黑树和链表性能对比


从上述例子中,红黑树的查询效率提升了将近一倍
总结来说,采用红黑树就是为了解决链表过长,查询效率过低的问题。

为什么在jdk1.8中红黑树的阈值设为8?

通过阅读源码可以发现,java8中的hashmap并不是一上来就用红黑树,而是设定了一个阈值,当链表node结点数大于8时使用红黑树。

所谓"鱼和熊掌不可兼得",红黑树查询虽快,但是插入的效率是偏慢的(红黑树为了维持"小中大"的结构,会牺牲插入的性能
所以为8 而不是6、7或其他数字,是因为java源码贡献者通过大量实验发现,xhdhxc碰撞发生8次以上的情况几乎不可能发生,为极端情况,此时链表的性能以及非常差了,权衡之下才换用红黑树,来提高性能,而链表转红黑树的过程也是需要消耗性能的,因此大多数情况下hashmap还是会使用链表。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。