Java笔试题集合部分简答


1、有几种常见集合?各有什么特点?

Collection是所有集合类的根接口,Collections是提供集合操作的工具类,常用的集合有:

Set代表无序集合,无序不可重复,有HashSet,TreeSet

List代表有序集合,有序可重复,有ArrayList,LinkedList

Map集合存储键值对,常用的有HashMap,TreeMap


2、在哪些场景使用这些集合?

List里存放的对象是有序的,同时也是可以重复的,其特点是List关注的是索引,拥有一系列和索引相关的方法,查询速度快,往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

ArrayList是基于数组的,在初始化ArrayList时,会构建空数组,当发觉同时添加一个或者是多个元素,数组长度不够时,就扩容。

LinkedList是基于链表的,它是一个双向链表,每个节点维护了一个prev和next指针。

总结:根据其特点,经常使用查询,list的实现类如ArrayList可以提供更快速的访问,如果经常添加删除元素,选择LinkedList基于链表更快的删除,如果想让容器的元素能够按照他们的插入次序进行有序存储,使用List,List是一个有序容器,他按照插入顺序进行存储。

Set不允许有重复对象,无序容器,无法保证每个元素的存储顺序,TreeSet通过Comparator维护一个排序顺序,如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。

以键和值的形式进行数据存储那么 Map。


private Set<Role> roles = new HashSet<Role>();

List list = new ArrayList<User>();

//将查询条件封装到map中

Map<String,Object> map = new HashMap<String,Object>();

map.put("reportDate", reportDate);


3、HashSet是怎么保证唯一性的?

HashSet的底层存储数据结构是哈希表, 它是根据哈希值和equals方法来确保集合元素的唯一性

原理:如果一个元素要存入,首先会判断集合是否存在与该元素的HashCode相同的元素, 如果不存在,则把元素存入HashSet集合,如果存在,则继续调用equals继续比较,如果equals方法返回true,证明集合已经存在该元素,所以不添加,如果返回false,证明该元素在集合中存在一个相同哈希值,内容不同的元素,所以把该元素添加到与该元素相同哈希值的元素后面。


4、HashMap的底层结构,实现原理?

JDK1.8之前

JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列。HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n-1)&hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法 换句话说使用扰动函数之后可以减少碰撞。

JDK 1.8 HashMap 的 hash 方法源码:


static final int hash(Object k){
    int h;
    // key.hashCode();返回散列值也就是hashcode
    // ^ : 按位异或
    // >>> : 无符号右移,忽略符号位,空位都已0补齐
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
复制代码

对比一下 JDK1.7的 HashMap 的 hash 方法源码.


static final int hash(int h){
    h ^= (h >>> 20) ^ (h >>>12);

    return h ^ (h >>> 7) ^ (h >>>4);
}复制代码


相比于JDK1.8 的hash 方法 ,JDK 1.7 的hash 方法的性能会稍差一点点,因为毕竟扰动了4 次。

所谓 “拉链法” 就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。


JDK1.8之后

相比于之前的版本,JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。

TreeMap、TreeSet以及JDK1.8之后的HashMap底层都用到了红黑树。红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。

编辑| Web小项目

作者:junxia

如果您认为阅读这篇博客让您有些收获,欢迎扫描下方二维码关注我们,与我们交流互动。

本公众号专注Java面试题目的收集和解析以及【Web项目】源码的分享。


以下为公众号截图,欢迎小伙伴们鼓励!


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值