当前位置: 首页 > news >正文

Java集合面试题(持续更新)

概念

数组和集合的区别,你用过哪些

  • 数组是固定的,一旦创建便不可改变。而集合是可变的,可以动态调整元素个数。
  • 数组可以存储基本数据类型和对象类型,但是集合只能存储对象。
  • 数组可以使用下标直接访问元素,而集合需要迭代器或者其他方法访问元素

我用过如下Java集合类:

  • ArrayList:动态数组,实现了List接口,支持动态增长
  • LinkList:双线链表,也实现了List接口,支持快速插入和删除
  • HashMap:基于hash表的map实现,存储key-value,通过key快速查找
  • HashSet:基于hash实现的set集合,存储唯一元素
  • TreeMap:基于红黑树实现的有序map集合,可以按照key的顺序排序
  • LinkHashMap:基于hash和双向链表实现的map集合,保持插入顺序和访问速度
  • ProorityQueue:优先队列,按照比较器或元素的自然顺序进行排序

说说Java中的集合

List

List是有序的Collection,使用这个接口可以精确的控制每个元素的位置,用户可以根据索引访问list中的元素。

  • ArrayList:是容量可变的非线程安全列表,其底层使用的是数组实现,当扩容时,会扩大创建更大的数组,然后将原数组复制到新数组。ArrayList可以对元素快速访问,但是随机插入删除很慢。
  • LinkList:本质是一个双向链表,与ArrayList相比,随机查找比较满,但是随机插入和删除比较快

Set

set不允许存在重复的元素,与list不同,set是无序的。

HashSet:是通过HashMap实现的,HashMap的key就是HashSet存储元素,其中的value值都是一样的,使set内元素保持唯一性。由于hashset由hashmap实现的,因此线程不安全。

LinkHashSet:继承自HashSet,使用双向链表保持元素插入的顺序,

TreeSet:通过TreeMap实现,添加数据按照比较规则将其插入合适的位置,保证插入数据的有序性。

Map

是一个键值对集合,存储键值之间的映射。key无序,要求唯一;value不要求有序,允许重复。map没有继承Collection,从map中获取元素时,只要给出键对象,就会返回相应的value。

HashMap:在Java8之前,hashmap采用数组+链表去实现的,数组是hashmap的主体,链表是为了解决hash冲突存储的(拉链法)。【ps:在Java8之前,当一个key要插入hashmap时,需要根据相应的hash公式计算出key该放在数组的哪个位置,但是数组长度有限,很可能出现撞车现象,那么此时我们在数组内存放一个链表,链表内存储键值对,然后将撞车的key插入到头部。这就是拉链法】。但是在Java8之后发生了改变,当链表长度大于8时,会将链表转化为红黑树。

LinkHashMap:继承自hashmap,底层还是基于链表+数组+红黑树数组。但是在上面结构的情况下,添加了一条双向链表,可以保持插入的顺序。

HashTable:数组+链表组成。

TreeMap:红黑树

ConcurrentHashMap:Node数组+链表+红黑树实现,是线程安全的(Java8之前是Segment锁,1.8之后采用synchronized实现)

Java中的线程安全集合是什么

java.util

vector:线程安全的动态数组,其内部方法基本都是经过synchronize修饰,但是如果不需要线程安全,不建议使用,同步是有额外开销的

HashTable:线程安全的hash表,给每个方法加上synchronized关键字,这样锁住的就是整个table对象。

java.util.concurrent

并发Map:

  • ConcurrentHashMap:他与HashTable的主要区别是二者加锁力度不同,在Java8之前,ConcurrentHashMap加的是分段锁,也就是Segment,每个Segment都含有table的一部分,这样不同分段之间的并发就不受影响。在Java8之后,他取消了Segment字段,直接在table元素上加锁,实现对每一行进行枷锁,进一步减少了并发冲突的概率。对于put操作,如果key对应的数组为null,则通过CAS操作将其设置为当前值,如果key对应的数组元素不为null,则对该元素使用sychronized关键字申请加锁,如果该链表的长度大于8,则将链表转化为红黑树。
  • ConcurrentSkipListMap:基于跳表算法的可排序的并发集合。

并发set:

  • ConcurrentSkipListSet:是线程安全的有序集合,底层是基于ConcurrentSkipListMap实现的
  • ConcurrentOnWriteAtrraySet:是线程安全的set实现,他是线程安全的无序集合。

并发list:

  • CopyOnWriteArrayList:他是ArrayList线程安全的变体,其中所有写操作都通过对底层数组进行全新复制来实现,允许存储null。当对象进行写操作时,使用lock进行同步处理,内部拷贝了原数组,并在新的数组上进行添加操作,最后将新数组覆盖掉旧数组。

Collections和Collention的区别

  • Collection时Java集合类的一个基础接口,他定义了一系列的通用操作和方法,如添加、删除、遍历等,用户同意操作和管理。List、Set都是他的实现类
  • Collentions是Java提供的一个工具类,位于java.util中,他提供了一系列的静态方法,用于对集合进行操作和算法,比如排序、查找、替换等。这些方法可以对实现了Collent的接口进行操作

遍历集合的方法

普通for循环

List<String> list = new ArrayList<>();

for(int i=0;i<list.size();i++){
    
}

增强for循环 也即是for-each

//这里不再定义集合,使用list代表集合

for(String element:list){
    //业务操作
}

Iterator迭代器

用来迭代遍历集合,用户要删除元素的状况

//这里不再定义集合了 使用list代替
Iterator<String> iterator = list.iterator();

while(iterator.hasNext()){
    String ele = iterstor.next();
    //业务操作
}

使用Java8后的Stream API

//这里不再定义list

list.forEach(element->log.info(element))

相关文章:

  • 动态规划01背包问题系列一>最后一块石头的重量II
  • Spring Boot使用JDBC /JPA访问达梦数据库
  • 安卓免费多功能工具:一站式解决 PDF 阅读、编辑、转换等需求
  • 基础算法总结
  • vue3:七、拦截器实现
  • PX4中的UAVCAN_V1的实现库libcanard与数据格式DSDL
  • 【微知】Mellanox驱动中to是什么?有哪些超时时间?(time out,心跳2s,reset 1分钟)
  • 正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-2.1 uboot简介
  • 算法-图-dijkstra 最短路径
  • Linux线程机制
  • 使用joblib 多线程/多进程
  • 锂电池升压到5V并且可以锂电池充电的芯片SM5401
  • K8S学习之基础十六:k8s中Deployment更新策略
  • AUTOSAR—TM模块介绍及使用概要
  • 深入剖析 Kubernetes 弹性伸缩:HPA 与 Metrics Server
  • 文件解析:doc、docx、pdf
  • 开发环境搭建-06.后端环境搭建-前后端联调-Nginx反向代理和负载均衡概念
  • RAG了解与实践
  • QEMU源码全解析 —— 块设备虚拟化(1)
  • MySQL root用户密码忘记怎么办(Reset root account password)
  • 中国预警机雷达有多强?可数百公里外看清足球轨迹
  • 重庆城市轨道交通拟听证调价:公布两套票价方案,正征求意见
  • 2人恶意传播刘国梁谣言被处罚,媒体:以法律利剑劈谣斩邪,加快推进依法治体
  • 光明日报社副总编辑薄洁萍调任求是杂志社副总编辑
  • 全国多家健身房女性月卡延长,补足因月经期耽误的健身时间
  • 首次带人形机器人走科技节红毯,傅利叶顾捷:没太多包袱,很多事都能从零开始