Java集合的常见面试题(全)

这里写目录标题

  • 前言
  • 常用的集合类有哪些
  • 集合底层数据结构
  • ArrayList 和 LinkedList 的区别
  • HashSet 如何检查重复
  • HashSet与HashMap的区别
  • HashMap 和 Hashtable 的区别
  • HashMap 的底层实现
  • HashMap 的长度为什么是 2 的幂次方
  • ConcurrentHashMap 和 Hashtable 的区别
  • HashMap源码细节
  • ConcurrentHashMap源码细节
  • Array 和 ArrayList 的区别
  • Collection 和 Collections的区别

前言

关于java集合的一些知识点可看我之前的文章进行预习
javaSE从入门到精通的二十万字总结(二)

下面的博文主要是java集合中的一些常见面试题以及一些知识点
在这里插入图片描述

在这里插入图片描述

常用的集合类有哪些

可以通过如上所示
主要的两个大类有Map接口和Collection接口

实现类底层元素
Arraylist底层是数组。
LinkedList底层是双向链表。
Vector底层是数组,线程安全的,效率较低,使用较少。
HashSet底层是HashMap,放到 HashSet集合中的元素等同于放到HashMap集合key部分了。
TreeSet底层是TreeMap,放到 TreeSet集合中的元素等同于放到TreeMap集合key部分了。
HashMap底层是哈希表。
Hashtable底层也是哈希表,只不过线程安全的,效率较低,使用较少。
Properties是线程安全的,并且 key 和value只能存储字符串String。
TreeMap底层是二叉树。TreeMap集合的 key可以自动按照大小顺序排序。

集合底层数据结构

  • list接口主要常用的实现类有
  1. ArrayList集合底层采用了数组这种数据结构,非线程安全
  2. LinkedList集合底层采用了双向链表的数据结构
  3. Vector集合底层采用了数组这种数据结构,线程安全的,所有的方法都有synchronized关键字修饰,比较安全但效率低,所以使用率低
  • set接口主要常用的实现类有
  1. HashSet集合在new的时候,底层实际上new了一个HashMap集合。向HashSet集合中存储元素,实际上是存储到HashMap集合中,HashMap集合是一个哈希表数据结构
  2. TreeSet集合实际是TreeMap,new TreeSet集合的时候,底层实际上new了一个TreeMap集合,和上面同理。采用了二叉树数据结构

Map集合和Collection集合没有关系,存储的方式不同
所有Map集合key元素无序不可重复
Map接口的常用实现类有

  • HashMap集合底层是哈希表数据结构,非线程安全
  • Hashtable集合是哈希表数据结构,线程安全,所有的方法都有synchronized关键字,效率比较低,使用比较少了
  • 还有一个接口SortedMap,本身不可重复无序,但是此处有自动排序,按照大小进行排序。此接口的实现类有TreeMap(二叉树结构)

ArrayList 和 LinkedList 的区别

这部分的知识主要涉及数组和双向链表的区别
两者都是不保证线程安全

再讲这部分知识的时候,涉及单链表和双向链表以及对比线性表的区别
可查看我之前写过的文章
【数据结构】顺序表及链表详细分析(全)

具体涉及单链表和双链表的创建可查看这篇代码
【leetcode】链表-设计链表(单双链表全)

HashSet 如何检查重复

当你把对象加⼊ HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加⼊的位置,同时也会与其他加⼊的对象的 hashcode 值作⽐较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。
但是如果发现有相同 hashcode 值的对象,这时会调⽤ equals() ⽅法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让加⼊操作成功。

HashSet与HashMap的区别

HashMapHashSet
实现Map接口实现Set接口
存储键值对仅存储对象
调用put()向map中添加元素调用add()方法向Set中添加元素

HashMap使用键(Key)计算Hashcode ,而HashSet使用成员对象来计算hashcode值

HashMap相对于HashSet较快,因为它是使用唯一的键获取对象

HashMap 和 Hashtable 的区别

  1. 线程是否安全: HashMap 是⾮线程安全的,HashTable 是线程安全的,因为 HashTable 内部的⽅法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使⽤ConcurrentHashMap 吧!);
  2. 效率: 因为线程安全的问题,HashMap 要⽐ HashTable 效率⾼⼀点。另外,HashTable 基本被淘汰,不要在代码中使⽤它
  3. 对 Null key 和 Null value 的⽀持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有⼀个,null 作为值可以有多个;HashTable 不允许有 null 键和 null 值,否则会抛出 NullPointerException
  4. 初始容量⼤⼩和每次扩充容量⼤⼩的不同
    创建时如果不指定容量初始值, HashMap 默认的初始化⼤⼩为16。之后每次扩充,容量变为原来的 2 倍。
    Hashtable 默认的初始⼤⼩为 11,之后每次扩充,容量变为原来的 2n+1。

HashMap 的底层实现

JDK1.8 之前 HashMap 底层是 数组和链表 结合在⼀起使⽤也就是 链表散列

JDK1.8 之后在解决哈希冲突时有了较⼤的变化,当链表⻓度⼤于阈值(默认为8)(将链表转换成红⿊树前会判断,如果当前数组的⻓度⼩于 64,那么会选择先进⾏数组扩容,⽽不是转换为红⿊树)时,将链表转化为红⿊树,以减少搜索时间

补充:红黑树转换是链表节点大于8且数组长度大于64

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

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

为了能让 HashMap 存取⾼效,尽量较少碰撞,也就是要尽量把数据分配均匀
⽤之前还要先做对数组的⻓度取模运算,得到的余数才能⽤来要存放的位置也就是对应的数组下标。这个数组下标的计算⽅法是“ (n - 1) & hash ”。

hash%length==hash&(length-1)的前提是 length 是 2的 幂次⽅

ConcurrentHashMap 和 Hashtable 的区别

  • 底层数据结构: JDK1.7 的 ConcurrentHashMap 底层采⽤ 分段的数组+链表 实现,JDK1.8 采⽤的数据结构跟 HashMap1.8 的结构⼀样,数组+链表/红⿊⼆叉树。Hashtable 和 JDK1.8 之前的 HashMap 的底层数据结构类似都是采⽤ 数组+链表 的形式,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突⽽存在的

  • 实现线程安全的⽅式(重要): ① 在 JDK1.7 的时候,ConcurrentHashMap(分段锁) 对整个桶数组进⾏了分割分段(Segment),每⼀把锁只锁容器其中⼀部分数据,多线程访问容器⾥不同数据段的数据,就不会存在锁竞争,提⾼并发访问率。 到了 JDK1.8 的时候已经摒弃了Segment 的概念,⽽是直接⽤ Node 数组+链表+红⿊树的数据结构来实现,并发控制使⽤synchronized 和 CAS 来操作。(JDK1.6 以后 对 synchronized 锁做了很多优化) 整个看起来就像是优化过且线程安全的 HashMap,虽然在 JDK1.8 中还能看到 Segment 的数据结构,但是已经简化了属性,只是为了兼容旧版本;② Hashtable(同⼀把锁) :使⽤ synchronized 来保证线程安全,效率⾮常低下。当⼀个线程访问同步⽅法时,其他线程也访问同步⽅法,可能会进⼊阻塞或轮询状态,如使⽤ put 添加元素,另⼀个线程不能使⽤ put 添加元素,也不能使⽤get,竞争会越来越激烈效率越低

HashMap源码细节

1.8之前的版本:数组+链表(使用了拉链法解决冲突)
1.8之后的版本:链表长度大于8的阈值,如果数组长度要大于64(转化为红黑树),如果数组长度小于64(扩容树组)

初始化的容量为16,扩容的时候为原来的2倍

加载因子0.75
加载因子是控制数组存放数据的疏密程度

  • 接近1的时候,数组数据密集,让其链表长度增加
  • 接近0的时候,数组数据稀疏,链表长度不长

以上两种,加载因子过大,导致元素查找效率降低(链表过长),利用率低。加载因子过小,利用率低(存放数据过于稀疏)。
综上所述,0.75的加载因子是很好的临界值

通过这个加载因子来考虑什么时候扩容:threshold = capacity * loadFactor
如果size大于等于threshold的时候,对数组进行扩容

put函数:(注意两者之后的区别)

  • 1.7版本:
    定位到的数组如果没有元素,则直接插入。如果有元素,则以这个元素为头结点,依次插入key比较,如果相同弄则进行覆盖(更新),不同则用头插法

  • 1.8版本:
    定位道德数组如果没有元素,则直接插入。如果有元素,则则以这个元素为头结点,依次插入key比较,如果相同弄则进行覆盖,不同则判断该节点是否为树节点,调用树的put节点将元素加入,如果不是则遍历链表之后进行尾结点插入

get函数此处比较简单(省略)

resize函数

每次的resize都要进行重新hash分配,并且会遍历hash表中的所有元素,比较耗时

ConcurrentHashMap源码细节

1.8以前的版本:分段锁+数组+链表

以下为1.8的版本:数组+链表+红黑树

put函数

  1. 通过key计算出hashcode,判断是否需要初始化
  2. 通过定位的key写入数组中,如果数组为空,则通过CAS进行写入。如果当前数组的位置不存在,则通过扩容。
  3. 以上情况都不满足则通过synchronized锁进行写入。数量如果大于TREEIFY_THRESHOLD 则进行树形化,在treeifyBin函数中判断数组长度,大于64才会转为红黑树

get函数

  1. 计算hash值,找到指定位置,如果头结点符合,则返回value值
  2. 头结点hash值小于0,说明正在扩容或者红黑树
  3. 如果是链表,则进行遍历

Array 和 ArrayList 的区别

Array 可以存储基本数据类型和对象,存储的数据都是固定大小
ArrayList 只能存储对象,存储的数据大小可以自动扩展

Collection 和 Collections的区别

Collection 提供了对集合对象进行基本操作的通用接口方法。其直接继承接口有List与Set
Collections是工具类,主要功能有用于对集合中元素进行排序、搜索以及线程安全等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1382439.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

集合面试题总结

集合 Collection接口:单列集合,用来存储一个一个的对象 List接口:存储有序的、可重复的数据,。 -->“动态”数组 实现类:ArrayList、LinkedList、Vector Set接口:存储无序的、不可重复的数据 实现类&…

10道集合框架面试题(含解析),来看看你会多少

1.Arraylist 与 LinkedList 异同 (1)是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; (2)底层数据结构: Arraylist 底层使用的是Object数组&#…

Java集合面试题(总结最全面的面试题)

集合容器概述 什么是集合 集合就是一个放数据的容器,准确的说是放数据对象引用的容器 集合类存放的都是对象的引用,而不是对象的本身 集合类型主要有3种:set(集)、list(列表)和map(映射)。 集合的特点 集合的特点…

Python编程练习与解答 练习65:温度换算表

编写一个程序,显示摄氏温度和华氏温度转换表。该表的行包括0-100摄氏度之间所有的温度,这些温度时10摄氏度的倍数,列上适当的标题,摄氏度和华氏度之间的换算公式可在互联网上找到。 # 转换公式为:f((c*9)/…

java语言【 #93. 温度换算】(已通过)

题目描述 ​ 读入一个实数表示的摄氏温度 C,将它转换为华氏温度 F 并输出。​ 公式如下: F1.8∗C32 输入 ​ 一个实数表示 C(0.0≤C≤100.0) 输出 ​ 将 C 转换成 F 的结果。 ​ 结果保留两位小数 样例输入 66.66样例输出 151…

热敏电阻-温度换算算法(分段线性拟合法)

概要 在工业上,会有各种读取环境温度,或读取目标物体温度的需求,通常用到的方案有:传感器测温;热敏电阻测温等。本篇着重讲解使用热敏电阻测温的方法。 热敏电阻 何为热敏电阻?热敏电阻即为热电偶传感器…

摄氏温度和华氏温度换算(vb源码)

【实例简介】初步涉及VB 【实例截图】 文件:590m.com/f/25127180-493490306-f0ccf8(访问密码:551685) 以下内容无关: -------------------------------------------分割线----------------------------------------…

DS18b20温度值换算

DS18B20 处理正负温度值。 寄存器格式 例子 //计算温度值 //参数 高字节&#xff0c;低字节 double CaculateTemp(uint8_t tmh, uint8_t tml) {uint8_t th;uint8_t tl;double temp 0;tl tml & 0x0F;//取低字节后四位th (tmh << 4) (tml >> 4);//取高字节后…

用Python制作温度换算模块

&#xff08;注&#xff1a;这里通用摄氏度&#xff0c;Python版本为3.8.5&#xff09; 今天教大家做一个温度换算模块&#xff0c;非常简单实用。 这张图是最终效果&#xff1a; &#xff08;CK指将摄氏度转换为开氏度&#xff0c;CRe指将摄氏度转换为列氏度&#xff09; …

c语言——统计分类

我们将一个班的成绩进行分类&#xff0c; 成绩60分以下的为c、成绩61-89分的为b&#xff0c;90分以上的为A //统计分类 /*我们将一个班的成绩进行分类&#xff0c; 成绩60分以下的为c、成绩61-89分的为b&#xff0c;90分以上的为A */ #include<stdio.h> int main() …

如何将Excel中的一列内容合并到一起显示?

最近在工作过程中遇到要将excel中一列内容合并到一个格里显示&#xff0c;经过查询可以通过如下实现&#xff0c;记录下来方便使用。 步骤&#xff1a; 打开excel&#xff0c;复制要整合的内容到excel的一列&#xff0c;在下面一个格里执行下面语句&#xff1a; CONCATENATE(TR…

Excel表格合并两列数据且保留全部内容

Excel表格如何能将两列数据合并成一列&#xff0c;保留两列的内容&#xff0c;且插入你需要的分隔符&#xff0c;看这里&#xff01; 方法超级简单&#xff0c;我还找了半个小时&#xff08;泪目&#xff09; 第一步&#xff1a;新建一个空白列 在需要合并列的位置上新建一个…

如何把Excel两列内容合并成一列内容

今天跟大家分享一下如何把俩列内容合并成一列内容 1.如下图表格中含有两列数据&#xff0c;现在我们先要将这两列数据合并到一个单元格中。 2.第一步我们选中全部单元格区域 3.然后我们点击下图选项&#xff08;Excel工具箱&#xff0c;百度即可了解详细下载安装信息&#xff0…

excel表格内容合并的技巧?

今天跟大家分享一下excel表格内容合并的技巧&#xff1f; 1.打开演示文件&#xff0c;如下图要求将多个表格合并到一起。 2.首先我们点击下图选项 3.点击【汇总拆分】-【合并多表】 4.勾选要合并的工作表 5.然后根据表格设置表头行数 6.最后我们点击【确定】即可完成 7.完成效果…

如何将Excel表格中的多列内容合并到一列

目录 方法一&#xff1a;对于数据量不大的情况&#xff0c;可以考虑如下方法&#xff1a; 方法二&#xff1a;当数据量过大或存在多张需要填充的表格时 方法一&#xff1a;对于数据量不大的情况&#xff0c;可以考虑如下方法&#xff1a; 步骤一&#xff1a;在第一列的最下方…

Excel快速合并,简单方法,轻松搞定!

想要高效完成工作&#xff0c;就必须掌握一些实用的工作技巧&#xff0c;来帮助我们更好更快的完成任务。 分享6个使用效率高达95%的Excel实用技巧&#xff0c;工作中经常被用到&#xff01; 1.多行数据合并&#xff1a; 制作表格时&#xff0c;如果我们需要将多行数据合并为…

Excel数据合并

1、字段合并 字段合并是指将某几个字段合并成一个新的字段。 我们可以使用CONCATENATE&#xff0c;&&#xff0c;DATE函数进行字段合并。 1.1、CONCATENATE CONCATENATE函数能够把它的所有参数连接起来。 我们选中D2单元格&#xff0c;点击插入函数&#xff0c;查找到CO…

新版火狐右键关闭标签

最好用firefox57版本&#xff0c;打开ini有多个功能&#xff0c;

火狐浏览器中设置打开新地址时,不会覆盖原页面的方法

近期使用火狐浏览器发现打开新标签页时总是会覆盖原页面&#xff0c;百度了好多方法都是在选项中-设置标签页&#xff0c; 然而&#xff0c;在我用的浏览器版本里均无此项可设置&#xff0c;一直百度总算找到一种办法&#xff0c;亲试绝对有效&#xff01; 1、本人用的是火狐浏…

火狐浏览器(69版)修改起始页,主页和新标签页

火狐浏览器的优点 火狐浏览器&#xff08;我使用的是68版&#xff09;的资源占用比chrome浏览器&#xff08;如谷歌&#xff0c;微软最新的Edge&#xff09;要小很多而且集成了两者的优点&#xff1a; 可以使用火狐账号登录 &#xff0c;这样各种信息都可以选择保留&#xff…