Java相关性知识-集合

集合容器

集合是用户存储数据的容器,其中包含:接口,实现,算法。
集合的特点:对象封装数据,并且可以根据对象的个数来决定时是还是数组。

集合类有哪些?
1.collection的子接口有List,Queue,Set.
2.Map接口实现的类主要HashMap,HashTable,Concurrentable
3.List接口实现的类主要是ArrayList,LinkedList Vector
4.Set接口实现的类:HashSet,TreeSet
在这里插入图片描述

相关的面试题(重点)

讲一讲ArrayList和LinkedList的区别是什么?

1.底层实现来说,ArrayList是基于动态数组来实现的,而LinkedList是基于双向链表来实现的。
2.访问数据的效率来说,ArrayList的效率要比LinkedList要高,因为ArrayList由相对应的下表,而LinkedList是需要移动指针进行查找。
3.添加和删除效率来说,LinkedList的效率要比ArrayList的效率要高,因为ArrayList要考虑数组的其他数据下标的移动,
4.内存占用方面来说,LinkedList要比ArrayList的更占内存,因为LinkedList每个节点不仅要存数据,还要存储两个引用。
如果你想频繁的读取集合中的元素的时候,ArrayList的效率要高,添加或者删除操作过多时,用LinkedList效率要高。

有了解过 HashMap 的具体实现么?

HashMap是基于Map接口实现的,允许使用null值和null键,并且是基于Hash算法实现的,但是不保证映射的顺序,也就是来说HashMap是乱序的。
HashMap底层实际上是一个“链表散列”的数据结构,即就是动态数组+链表+红黑树(JDK 1.8)
实现过程 HashMap是基于Hash算法实现的
1.当我们往哈希表中添加数据的时候,会使用key的HashCode()方法来计算当前对象在数组中的下标
2.存储数据时,如果哈希值相同的key,此时有两种情况,如果key值相同,直接覆盖原先的value,如果不相同,则将当前key-value放入该链表中 (尾插法)。
3.获取数据的时候,通过Hash值找到对应的数组下标,进一步判断key值是否相等。

说一下HashMap的put操作流程

当我们在进行put操作的时候,
1.首先判断键值对数组是否为空或者为null,否则调用realize()进行扩容。
2.通过key值计算hash值,(调用Hash方法,hash方法实际是让key.hashCode()与key.hashCode()>>>16进行异或操作,高16bit补0,一个数和0异或不变,作用是为了减少Hash冲突)得到相应的索引i,如果数组的i号位置为null直接新建节点添加,这个时候判断链表链表的长度是否大于8,如果大于8的话就会转成红黑树,一红黑树的方式进行插入,否则就以链表的方式进行插入,遍历过程中,如果发现key值已经存在就直接覆盖value值即可
3.如果数组的i好位置不为空,就进行判断收个元素是否和key值相同如果相同就直接覆盖,否则就先判断这个位置是不是红黑树,如果是红黑树就按照红黑树的步骤及逆行插入,不是就按照链表的方法插入
4.插入成功后,判断size是否大于最大容量,如果超过了就进行扩容。
在这里插入图片描述

List 和 Set 的区别

List和Set都是继承自Collection接口
List特点:一个是有序(元素存入集合的顺序和去除的顺序一致),可以存在重复的元素,可以插入值,元素都有索引,实现得类由ArayList LinkedList 和vector。
Set特点:无序,不可以存储重复值,必须保存元素的唯一性,常用的类时HashSet,TreeSet,LinkedHashSet。
Set检索元素效率低下,插入和删除效率高,插入和删除不会引起元素位置改变
List检索元素位置效率高,插入和删除效率低,而且hi引起其他元素位置的改变。

HashMap和HashSet的区别

HashMap 实现了Map接口 存储方式是以键值对的方式存储,调用put方法来添加数据,而且使用key值计算Hashcode。
HashSet实现了Set接口,是存储对象,调用add的方法来添加数据。并且时使用对象来计算hashcode的值,调用equal方法来判断对象的相等性,会比HashMap要慢一些。

Queue中的poll方法和remove方法有啥区别

相同点:都是从队列中返回并删除第一个元素,
不同点:poll()如果没找到会返回一个null 而remove()会抛出一个NoSuchElementException 异常,

HashMap的扩容方式

判断数组是否为空或者length=0,就调用resize()进行行扩容,而且每次扩容就是会扩展两倍,并且扩容后还要调整对象的位置(要么元素在原位置,要么就移动到偏移量两倍的位置

为什么HashMap中String、Integer这样的包装类适合作为Key?

String,Integer等包装类的特征能够保证Hash值的不可更改性,和计算准确性,有效的减少Hash冲突的概率,因为都是final类型,即就是不可改变,保证了key的不可更改性,而且也重写了equal() hashcode()等方法,不容易出现哈希值计算错误的情况。

HashMap 的长度为什么是2的幂次方?

可以是数据九年云的非陪,尽可能地减少Hash冲突
解决哈希冲突可以使用连地址法的方式来解决,或者使用和合理的hash函数或者引入红黑树来降低遍历的时间复杂度,来避免哈希冲突

HashMap 与 HashTable 有什么区别?

1.线程安全方面,HashMap不是线程安全的,而HashTable是线程安全的内置方法都经过sqnchronized修饰的
2.效率 效率HashMap的效率要比HashTable的效率要高一些
3.对于null值和null键的支持,前者是可以允许多个键的值为null,但是null键只能有一个,后者是不能有null键否则就会抛出异常
4.初始容量和扩容的大小不同 建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。②创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为2的幂次方大小
5.底层数据结构 前者是在JDK1.8之后是数组+链表+ 红黑树,后者没有这样的机制。
6.继承的父类不同:
HashMap继承自AbstractMap类。但二者都实现了Map接口。
Hashtable继承自Dictionary类。

如何决定使用 HashMap 还是 TreeMap?

在Map中插入删除和定位这类操作使用前者,如果想对元素进行有序地遍历使用后者。
HashMap 和 ConcurrentHashMap 的区别?
线程安全:前者是线程不安全的,后者是线程安全的,并且对于锁的粒度更精细了一些从而使并发性能更好。前者的键值对允许有null 但是后者不允许

ConcurrentHashMap 和 Hashtable 的区别?

二者的主要区别使在于实现线程安全上的方式不同
底层:JDK1.7 ConcurrentHashMap底层采用分段数组+链表的方式实现,1.8之后和HashMap相同,数组+链表/红黑树,Hashtable 的底层是数组+链表
实现锁的方式,前者使用分段锁,以提高并发性能,时使用synchronized和CAS操作,而后者是使用一把锁,锁的粒度比较粗,效率比较低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值