撩课-Java每天10道面试题第6天
51.HashMap的实现原理
HashMap的主干是一个Entry数组。
Entry是HashMap的基本组成单元,
每一个Entry包含一个key-value键值对。 HashMap基于hashing原理,
我们通过put()和get()方法储存和获取对象。
当我们将键值对传递给put()方法时,
它调用键对象的hashCode()方法
来计算hashcode,
让后找到bucket位置来储存值对象。
当获取对象时,
通过键对象的equals()方法
找到正确的键值对,
然后返回值对象。
HashMap使用链表来解决碰撞问题,
当发生碰撞了,
对象将会储存在链表的下一个节点中。
HashMap在每个链表节点中储存键值对对象。 当两个不同的键对象的hashcode
相同时会发生什么?
它们会储存在同一个bucket位置的链表中。
键对象的equals()方法用来找到键值对。 因为HashMap的好处非常多,
我曾经在电子商务的应用中使用HashMap作为缓存。
因为金融领域非常多的运用Java,
也出于性能的考虑,
我们会经常用到HashMap和ConcurrentHashMap。 HashMap由数组+链表组成的,
数组是HashMap的主体,
链表则是主要为了解决哈希冲突而存在的,
如果定位到的数组位置不含链表
当前entry的next指向null,
那么对于查找,
添加等操作很快,
仅需一次寻址即可;
如果定位到的数组包含链表,
对于添加操作,
其时间复杂度为O(n),
首先遍历链表,
存在即覆盖,
否则新增;
对于查找操作来讲,
仍需遍历链表,
然后通过key对象的equals方法逐一比对查找。
所以,性能考虑,HashMap中的链表出现越少,
性能才会越好。
52.List、Set、Map之间的区别
List、Set是实现了Collection接口的子接口;
而Map是另一个集合接口。 1元素重复性:
List允许有重复的元素。
任何数量的重复元素
都可以在不影响现有重复元素的值
及其索引的情况下插入到List集合中; Set集合不允许元素重复。
Set以及所有实现了Set接口的类
都不允许重复值的插入,
若多次插入同一个元素时,
在该集合中只显示一个; Map以键值对的形式对元素进行存储。
Map不允许有重复键,
但允许有不同键对应的重复的值; 2.元素的有序性: List及其所有实现类保持了
每个元素的插入顺序; Set中的元素都是无序的;
但是某些Set的实现类
以某种殊形式对其中的元素进行排序,
如:LinkedHashSet按照元素的
插入顺序进行排序; Map跟Set一样对元素进行无序存储,
但其某些实现类对元素进行了排序。
如:TreeMap根据键对其中的元素进行升序排序; 3.元素是否为空值:
1.List允许任意数量的空值;
2.Set最多允许一个空值的出现;
当向Set集合中添加多个null值时,
在该Set集合中只会显示一个null元素
3.Map只允许出现一个空键,
但允许出现任意数量的空值;
---------------------------------
总结:
List中的元素:
有序、可重复、可为空;
Set中的元素:
无序、不重复、只有一个空元素;
Map中的元素:
无序、键不重,值可重、可一个空键、多可空值;
53.HashMap 的长度为什么是2的幂次方
1.减小哈希冲突概率
假如当前Entry数组长度为len,
插入节点时,
需要对key的hashcode进行二次哈希,
然后跟len-1相与
得到的值一定小于len,避免数组越界 如果len是2的N次方,
那么len-1的后N位二进制一定是全1 假设有两个key,
他们的hashcode不同,
分别为code1和code2
code1和code2分别与一个后N位全1的二进制相与,
结果一定也不同
但是,如果code1和code2分别
与一个后N位非全1的二进制相与,
结果有可能相同 也就是说,
如果len是2^N,
不同hashcode的key
计算出来的数组下标一定不同;
否则,
不同hashcode的key
计算出来的数组下标一定相同。 所以HashMap长度为全1,
可以减小哈希冲突概率。
----------------------
2.提高计算下标的效率
如果len的二进制后n位非全1,
与len-1相与时,
0与1相与需要取反。
如果len的二进制后n位全1,
完全不需要取反。 如果len为2^N,
那么与len-1相与,
跟取余len等价,
而与运算效率高于取余。
如果len不是2^N,
与len-1相与,
跟取余len不等价。
54.集合框架中的泛型有什么优点?
首先,
了解一下Java关于泛型的概念。
泛型,在C++中被称为模板,
就是一种抽象的编程方式。
当我们定义类和方法的时候,
可以用一种通用的方式进行定义,
而不必写出具体的类,
这些未知的东西会在真正使用的时候在确定。 对于集合类来说,
它们可以存放各种类型的元素。
如果在存放之前,
就能确定元素的类型,
那么就可以更加直观,
也让代码更加简洁。 说明:
java的泛型是停留在编译层的,
也就是说JVM在对待泛型数据的时候,
依然会把它们看成是Object类型,
只不过在使用这些元素的时候,
JVM会自动帮助我们进行相应的类型转换。 总结:
集合使用泛型之后,
可以达到元素类型明确的目的,
避免了手动类型转换的过程,
同时,也让我们更加明确
容器保存的是什么类型的数据。
55.我们能否使用任何类作为Map的key?
1、可以
但是做为key的数据有如下要求: 2、首先,
要求明确一点Map集合存储数据的
主要目的是为了查找
而List集合是为了输出 3、既然是查找那么就要涉及到对象比较
我们说了如果要进行对象比较
就必须覆写Object类中的equals()、hasCode()
至少覆写equals()方法 简单理解:
自己定义的类如果要想实现对象比较
就必须至少覆写equals()方法 4、或则这么说只要是自己定义的类
要想将其作为key
就必须覆写equals()方法 5、实际工作中 key的类型一定是String型
(95%通用) 其余的5%是没事找事的 6、按标准开发、你会感到事半功倍,
不要没事给自己找事,
当然求知精神是值得肯定的。
56.Map接口提供了哪些不同的集合视图?
Map接口提供了三个集合视图: 1.Set keyset():
返回map中包含的所有key的一个Set视图。
集合是受map支持的,
map的变化会在集合中反映出来,
反之亦然。
当一个迭代器正在遍历一个集合时,
若map被修改了(除迭代器自身的移除操作以外),
迭代器的结果会变为未定义。
集合支持通过
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作进行元素移除,
从map中移除对应的映射。
它不支持add和addAll操作。 2.Collection values():
返回一个map中包含的
所有value的一个Collection视图。
这个collection受map支持的,
map的变化会在collection中反映出来,
反之亦然。
当一个迭代器正在遍历一个collection时,
若map被修改了(除迭代器自身的移除操作以外),
迭代器的结果会变为未定义。
集合支持通过
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作进行元素移除,
从map中移除对应的映射。 它不支持add和addAll操作。 3.Set> entrySet():
返回一个map钟包含的
所有映射的一个集合视图。
这个集合受map支持的,
map的变化会在collection中反映出来,
反之亦然。
当一个迭代器正在遍历一个集合时,
若map被修改了
除迭代器自身的移除操作,
以及对迭代器返回的entry进行setValue外,
迭代器的结果会变为未定义。
集合支持通过
Iterator的Remove、
Set.remove、
removeAll、
retainAll和clear操作进行元素移除,
从map中移除对应的映射。
它不支持add和addAll操作。
57.哪些集合类是线程安全的?
在集合框架中,有些类是线程安全的,
这些都是jdk1.1中的出现的。
在jdk1.2之后,
就出现许许多多非线程安全的类。
下面是这些线程安全的同步的类:
vector:
就比arraylist多了个同步化机制(线程安全),
因为效率较低,
现在已经不太建议使用。
在web应用中,
特别是前台页面,
往往效率(页面响应速度)是优先考虑的。 statck:堆栈类,先进后出 hashtable:就比hashmap多了个线程安全 enumeration:枚举,相当于迭代器 除了这些之外,
其他的都是非线程安全的类和接口。 线程安全的类其方法是同步的,
每次只能一个访问。
是重量级对象,
效率较低。
58.队列和栈是什么,列出它们的区别?
队列(Queue):
是限定只能在表的一端进行
插入和在另一端进行删除操作的线性表; 栈(Stack):
是限定只能在表的一端
进行插入和删除操作的线性表。 区别如下:
一、规则不同
1. 队列:先进先出(First In First Out)FIFO
2. 栈:先进后出(First In Last Out )FILO 二、对插入和删除操作的限定不同
1. 队列:只能在表的一端进行插入,
并在表的另一端进行删除;
2. 栈:只能在表的一端插入和删除。 三、遍历数据速度不同
1. 队列:基于地址指针进行遍历,
而且可以从头部或者尾部进行遍历,
但不能同时遍历,
无需开辟空间,
因为在遍历的过程中不影响数据结构,
所以遍历速度要快; 2. 栈:只能从顶部取数据,
也就是说最先进入栈底的,
需要遍历整个栈才能取出来,
而且在遍历数据的同时需要
为数据开辟临时空间,
保持数据在遍历前的一致性。
59.哪一个List实现了最快插入?
LinkedList和ArrayList
是另个不同变量列表的实现。
ArrayList的优势在于动态的增长数组,
非常适合初始时总长度未知的情况下使用。
LinkedList的优势在于在中间位置插入和删除操作,
速度是最快的。 LinkedList实现了List接口,
允许null元素。
此外LinkedList提供额外的
get,remove,insert方法
在LinkedList的首部或尾部。
这些操作使LinkedList可被
用作堆栈(stack),
队列(queue)
或双向队列(deque)。 ArrayList实现了可变大小的数组。
它允许所有元素,
包括null。
每个ArrayList实例都有一个容量(Capacity),
即用于存储元素的数组的大小。
这个容量可随着不断添加新元素而自动增加,
但是增长算法并没有定义。
当需要插入大量元素时,
在插入前可以调用ensureCapacity方法来
增加ArrayList的容量以提高插入效率。
60.什么时候使用ConcurrentHashMap?
快速失败的Java迭代器
可能会引发ConcurrentModifcationException
在底层集合迭代过程中被修改。
故障安全作为发生在实例中的一个副本
迭代是不会抛出任何异常的。
快速失败的故障安全范例定义了
当遭遇故障时系统是如何反应的。
例如,用于失败的快速迭代器ArrayList
和用于故障安全的迭代器ConcurrentHashMap。 ConcurrentHashMap被作为
故障安全迭代器的一个实例,
它允许完整的并发检索和更新。
当有大量的并发更新时,
ConcurrentHashMap此时可以被使用。
这非常类似于Hashtable,
但ConcurrentHashMap不锁定
整个表来提供并发,
所以从这点上ConcurrentHashMap的性能
似乎更好一些。
所以当有大量更新时
ConcurrentHashMap应该被使用。
撩课-Java每天10道面试题第6天的更多相关文章
- 撩课-Java每天10道面试题第7天
撩课Java+系统架构 视频 点击开始学习 61.什么是并发修改异常? 什么是并发修改异常: 当我们在遍历实现了collection接口 与iterator接口的集合时(List.Set.Map), ...
- 撩课-Java每天10道面试题第4天
撩课Java+系统架构 视频 点击开始学习 31.静态变量和实例变量的区别? 静态变量也叫类变量, 这种变量前加了static修饰符. 可以直接用类名调用, 也可以用对象调用, 而且所有对象的同一个类 ...
- 撩课-Java每天10道面试题第1天
1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...
- 撩课-Java每天10道面试题第5天
41.Iterator.ListIterator 和 Enumeration的区别? 迭代器是一种设计模式, 它是一个对象, 它可以遍历并选择序列中的对象, 而开发人员不需要了解 该序列的底层结构. ...
- 撩课-Java每天10道面试题第3天
21.final, finally, finalize的区别 1.final修饰符(关键字). 被final修饰的类, 就意味着不能再派生出新的子类, 不能作为父类而被子类继承. 因此一个类不能既被a ...
- 撩课-Java每天10道面试题第2天
11.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面, 以便更充分地注意与当前目标有关的方面. 抽象并不打算了解全部问题,而只是选择其中的一部分, 暂时不用部分细 ...
- 撩课-Java每天5道面试题第10天
撩课Java+系统架构 视频 点击开始学习 81.Servlet的会话机制? HTTP 是一种无状态协议, 这意味着每次客户端检索网页时, 都要单独打开一个服务器连接, 因此服务器不会记录下 先前客户 ...
- 撩课-Java每天5道面试题第13天
撩课Java+系统架构点击开始学习 96.JDBC操作数据库的步骤 ? .加载数据库驱动 .创建并获取数据库链接 .创建jdbc statement对象 .设置sql语句 .设置sql语句中的参数(使 ...
- 撩课-Java每天5道面试题第15天
撩课Java+系统架构点击开始学习 106.什么是Hibernate的并发机制?怎么去处理并发问题? a.Hibernate的Session对象是非线程安全的, 对于单个请求,单个会话, 单个的工作单 ...
随机推荐
- Problem D: GJJ的日常之暴富梦(水题)
Contest - 河南省多校连萌(四) Problem D: GJJ的日常之暴富梦 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 693 Solve ...
- git命令合集及github的克隆推送
安装git 初始化仓库 提交相关 撤销相关 远程推送 分支相关 其他 遇到的错误 github的克隆上传 此文章只是对命令的一个统计,起备忘和复习git只是的作用,不建议从没接触过git的同学通过它来 ...
- psp0级报告
计划 1.1需求描述: 现在市场上有很多的面向小学生的题卡,但是这习题卡不但价格昂贵,而且每次做题的内容基本都是固定.针对这些问题,开发出了这款网页在线答题系统,每次的题目都有所不同,可以跟快更好提高 ...
- leetcode-887-三维形体投影面积
题目描述: 在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. ...
- 2016级算法第六次上机-G.ModricWang likes geometry
1116 ModricWang likes geometry 思路 难题,非常考察几何知识,放在这里作为计算几何场次的最难的题. 原题地址 原版题解 代码
- SSAS有几种模式?
SQL2012中两种,SQL2016好像有三种,下面的第三种好像是2016才有.
- 常见的http错误提示
1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明100 (继续) 请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101 (切换协议 ...
- Vue项目开发目录结构
最近做一些CI+Vue开发的简单项目,由于刚开始一直从事后端,对Vue了解不是很多,fork了团队的项目代码发现项目的文件夹很多,一时间有些懵,上网上参考了部分资料,博客园中的放晴的天空与狮子爱吃草两 ...
- 【ORACLE】Bulk Processing with BULK COLLECT and FORALL
https://orablogspot.blogspot.com/2014/09/ https://blogs.oracle.com/oraclemagazine/bulk-processing-wi ...
- 本地jar包 安装到本地仓库中的命令
maven 项目 本地jar包 安装到本地仓库中去: 首先进入到该文件所在文件夹内 若不在直接绝对路径就可以.注意命令中的空格 mvn install:install-file -Dfile=文件名 ...