JAVA 学习 面试(八)集合类

集合类

集合类-思维导图

集合(Collection)

1、 List列表 : 有序 可重复

1、ArrayList : 数组列表 ,内部是通过Array实现,对数据列表进行插入、删除操作时都需要对数组进行拷贝并重排序,因此在知道存储数据量时,尽量初始化初始容量,提升性能 。
2、LinkedList : 双向链表  每个元素都有指向前后元素的指针,顺序读取的效率较高,随机读取的效率较低 
3、Vector : 向量 , 线程安全的列表,与ArrayList 一样也是通过数组实现的
4、Stack : 栈 , 后进先出 LIFO , 继承自Vector,也是用数组,线程安全的栈
类型底层实现线程安全扩容方式特点
ArrayList数组初始容量是 10,扩容因子是 0.5查询快,增删慢
LinkedList链表没有扩容的机制查询慢,增删快
Vector数组默认初始容量为10,扩容因子是 1查询快,增删慢

2、Queue队列:有序 可重复

1、ArrayDeque :  数组实现的的双端队列, 可以在队列两端插入和删除元素 
2、LinkedList : 也属于双端队列 
3、PriorityQueue : 优先队列  ,数组实现的二叉树, 完全二叉树实现的小顶堆(可改变比较方法)

3、Set集合: 无序 不重复

1、HashSet 基于哈希实现的集合, 链表形式
2、LinkedHashSet 
3、TreeSet 红黑树结构 
类型底层实现线程安全扩容方式特点
HashSet基于HashMap实现添加元素时,table数组扩容为16,加载因子为0.75无序
LinkedHashSet基于LinkedHashMap初始容量为16,临界值为12,以后再次扩容,扩容2倍有序
TreeSet基于TreeMap实现容量翻倍有序
集合(Collection)和数组的区别
  • 2、数组的长度是固定的,集合长度是可以改变的,提供很多成员方法。
  • 3、数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)。(当将元素放入集合时,它们会被转换成Object类型,之后在访问集合中的元素时需要进行强制类型转换。这种设计虽然方便,但也带来了类型不安全的隐患,以及类型转换的性能损失。)
  • 4、数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。
工具
  • 遍历集合:Iterator 和 Enumeration
  • 操作集合:Arrays 和 Collections
Map
1、HashMap 哈希映射 无序 , key 和 value 都可以为null 
2、TreeMap 红黑树实现的, 可排序, 红黑树是一种自平衡二叉查找树
3、LinkedHashMap  链表映射 ,继承于HashMap,又实现了双向链表的特性 ,保留了元素插入顺序 
类型底层实现线程安全扩容方式特点
HashMap数组+红黑树初始容量是 16,2倍扩容无序集合
LinkedHashMap基于HashMap,并自己维持了一个双向链表,按照插入顺序进行访问,实现了LRU算法初始容量是 16,2倍扩容有序集合
CocurrentHashMapSegments数组+ReentrantHashMap(作为互斥锁来控制并发访问)+链表,采用分段锁保证安全链表元素超8个,数组大小超64,转红黑树无序集合,性能比HashTable好
HashTable数组+链表初始大小为11,扩容为2n+1无序集合
TreeMap基于红黑树2倍有序集合
  • List:有序、可重复。
  • Set:无序、不可重复的集合。重复元素会覆盖掉。
  • Map:键值对,键唯一、值不唯一。Map 集合中存储的是键值对,键不能重复,值可以重复。
LinkedHashMap

LinkedHashMap继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题。在一些场景下,该特性很有用,比如缓存。

img

LinkedHashMap实现LRU

accessOrder用于决定具体的迭代顺序:

当accessOrder标志位为true时,put和get方法均有调用recordAccess方法,将当前访问的Entry(put进来的Entry或get出来的Entry)移到双向链表的尾部,双向链表中的元素按照访问的先后顺序排列。

当标志位accessOrder的值为false时,只有put方法会调用recordAccess,即每次put到LinkedHashMap中的Entry都放在双向链表的尾部,按照Entry插入LinkedHashMap到中的先后顺序排序

public class LRU<K,V> extends LinkedHashMap<K, V> implements Map<K, V>{private static final long serialVersionUID = 1L;public LRU(int initialCapacity,float loadFactor,boolean accessOrder) {super(initialCapacity, loadFactor, accessOrder);}/** * @description 重写LinkedHashMap中的removeEldestEntry方法,当LRU中元素多余6个时,*              删除最不经常使用的元素 **/@Overrideprotected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {// TODO Auto-generated method stubif(size() > 6){return true;}return false;}public static void main(String[] args) {LRU<Character, Integer> lru = new LRU<Character, Integer>(16, 0.75f, true);String s = "abcdefghijkl";for (int i = 0; i < s.length(); i++) {lru.put(s.charAt(i), i);}System.out.println("LRU中key为h的Entry的值为: " + lru.get('h'));System.out.println("LRU的大小 :" + lru.size());System.out.println("LRU :" + lru);}
}
hashMap和LinkedHashMap区别
  • 插入顺序:HashMap不保证映射的顺序,而LinkedHashMap会根据元素插入的顺序维护一个双向链表,因此保证了映射的顺序,可以通过get操作访问元素的插入顺序。
  • 迭代顺序:LinkedHashMap迭代元素的顺序是插入顺序,而HashMap的迭代顺序是随机的。
  • 性能:由于LinkedHashMap在底层额外维护了一个双向链表,因此在插入或删除元素时需要更多的操作,因此LinkedHashMap的性能通常比HashMap要低,内存占用通常比HashMap要高一些。
hashMap和TreeMap区别
  • 插入顺序:HashMap不保证映射的顺序,而TreeMap会根据元素的键值进行排序,因此保证了映射的顺序。
  • 元素访问时间复杂度:HashMap的元素访问时间复杂度是常数级别的,即O(1),而TreeMap的元素访问时间复杂度是基于红黑树的复杂度,通常是O(log(n))。
  • 键的类型:HashMap可以使用任何类型的对象作为键,只要它们能正确的实现hashCode()和equals()方法,而TreeMap的键必须实现Comparable接口或提供自定义的Comparator比较器来进行比较。
  • 内存占用:由于TreeMap需要维护红黑树的结构,因此它的内存占用相对较高。而HashMap在元素较少时,占用内存较小。
HashMap原理
  • HashMap在Jdk1.8以后是基于数组+链表+红黑树来实现的,特点是,key不能重复,可以为null,线程不安全

  • HashMap的扩容机制:

HashMap的默认容量为16,默认的负载因子为0.75,当HashMap中元素个数超过容量乘以负载因子的个数时,就创建一个大小为前一次两倍的新数组,再将原来数组中的数据复制到新数组中。当数组长度到达64且链表长度大于8时,链表转为红黑树

  • HashMap存取原理:

(1)计算key的hash值,然后进行二次hash,根据二次hash结果找到对应的索引位置

(2)如果这个位置有值,先进性equals比较,若结果为true则取代该元素,若结果为false,就使用高低位平移法将节点插入链表

  • 为什么不一开始就使用红黑树?

​ 因为直接采用红黑树的话每次加入元素需要进行平衡,而在超过8时再旋转变为红黑树可以达成平衡,因为大部分哈希槽的元素个数正态分布在8个左右,所以此时变为红黑树也满足了查找的效率。

- 想要线程安全的哈希表
(1)使用ConcurrentHashMap
(2)使用HashTable
(3)Collections.synchronizedHashMap()方法
## hash表:
构造:① 直接定址法;②平方取中法;③折叠法;④除留取余法
冲突解决:① 开放定址法(线性探测)② 链地址法
HashTable与HashMap的区别
  • (1)HashTable的每个方法都用synchronized修饰,因此是线程安全的,但同时读写效率很低

  • (2)HashTable的Key不允许为null

  • (3)HashTable只对key进行一次hash,HashMap进行了两次Hash

  • (4)HashTable底层使用的数组加链表

ConcurrenHashMap与HashTable的区别

ConcurrentHashMap性能更高,它基于分段锁+CAS 保证线程安全,分段锁基于 synchronized 实现,它仅仅锁住某个数组的某个槽位,而不是整个数组

  1. ConcurrentHashMap 没有大量使用 synchronsize 这种重量级锁。而是在一些关键位置使用乐观锁(CAS), 线程可以无阻塞的运行。
  2. ConcurrentHashMap读方法没有加锁
  3. ConcurrentHashMap扩容时老数据的转移是并发执行的,这样扩容的效率更高。
ArrayList和LinkedList的区别

ArratList的底层使用动态数组,默认容量为10,当元素数量到达容量时,生成一个新的数组,大小为前一次的1.5倍,然后将原来的数组copy过来;

因为数组有索引,所以ArrayList查找数据更快,但是添加数据效率更低

LinkedList的底层使用链表,在内存中是离散的,没有扩容机制;LinkedList在查找数据时需要从头遍历,所以查找慢,但是添加数据效率更高

如何保证ArrayList的线程安全?
(1)使用collentions.synchronizedList()方法为ArrayList加锁
(2)使用Vector,Vector底层与Arraylist相同,但是每个方法都由synchronized修饰,速度很慢
在Queue接口中, poll() 和 remove() 方法都用于从队列中移除并返回队头的元素。
如果队列为空,即没有元素可供移除时, pol0 方法会返回null。它是一个安全的方法不会抛出异常。
remove()在没有元素可供移除时,会抛出NoSuchElementException 异常。
怎么确保集合不可更改?

Java 集合框架提供了一些不可变集合类,如不可变列表(ImmutableList)、不可变集合(ImmutableSet)和不可变映射(ImmutableMap)。

List<String> list = ImmutableList.of("a", "b", "c");
Set<String> set = ImmutableSet.of("x", "y", "z");
Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 2, "c", 3);
List<String> list2 = ImmutableList.<String>builder().addAll(list1).add("d").build();

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GAMES101】Lecture 09 重心坐标

我们之前说着色过程中以及这个计算法线的时候需要用到这个插值&#xff08;Interpolation&#xff09;&#xff0c;然后插值是通过这个重心坐标&#xff08;Barycentric Coordinates&#xff09;来实现的 目录 重心坐标 插值 重心坐标 注意哈我们这里说的三角形的重心坐标并…

RK3399平台开发系列讲解(USB篇)BusHound 工具使用介绍

🚀返回专栏总目录 文章目录 一、BusHound简介二、BusHound的下载三、BusHound设备窗口四、BUSHound发送命令窗口沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 BusHound软件是由美国perisoft公司研制的一种专用于PC机各种总线数据包监视和控制的开发工具软件,其名…

【GitHub项目推荐--一款美观的开源社区系统】【转载】

推荐一款开源社区系统&#xff0c;该系统基于主流的 Java Web 技术栈&#xff0c;如果你是一名 Java 新手掌握了基本 JavaEE 框架知识&#xff0c;可以拿本项目作为练手项目。 开源社区系统功能还算完善包含发布帖子、发布评论、私信、系统通知、点赞、关注、搜索、用户设置、…

What is `Filter` does?

过滤器&#xff08;Filter&#xff09;是Java Servlet规范中的一部分&#xff0c;它提供了一种在请求到达目标资源之前或响应发送给客户端之前进行预处理和后处理的能力。 通过编写自定义的过滤器类并将其注册到Web应用程序中&#xff0c;开发者可以实现诸如登录验证、权限控制…

边缘计算及相关产品历史发展

边缘计算及相关产品历史发展 背景边缘计算的历史CDN&#xff08;Content Delivery Network&#xff09;Cloudlet雾计算MEC&#xff08;Multi-Access Edge Computing&#xff0c;MEC&#xff09; 边缘计算的现状云计算厂商硬件厂商软件基金会 背景 最近&#xff0c;公司部分业务…

RT-DETR优化改进:IoU系列篇 | Focaler-IoU​​​​​​​更加聚焦的IoU损失Focaler-IoU |2024年最新发表

🚀🚀🚀本文改进:Focaler-IoU更加聚焦的IoU损失Focaler-IoU,能够在不同的检测任务中聚焦不同的回归样本,使用线性区间映射的方法来重构IoU损失 🚀🚀🚀RT-DETR改进创新专栏:http://t.csdnimg.cn/vuQTz 🚀🚀🚀学姐带你学习YOLOv8,从入门到创新,轻轻松松搞…

Redis中BigKey的分析与优化

Redis中BigKey的分析与优化 Redis以其出色的性能和易用性&#xff0c;在互联网技术栈中占据了重要的地位。 但是&#xff0c;高效的工具使用不当也会成为性能瓶颈。在Redis中&#xff0c;BigKey是常见的性能杀手之一&#xff0c;它们会消耗过多的内存&#xff0c;导致网络拥塞…

【每日一题】最大交换

文章目录 Tag题目来源解题思路方法一&#xff1a;暴力法方法二&#xff1a;贪心 写在最后 Tag 【暴力法】【贪心法】【数组】【2024-01-22】 题目来源 670. 最大交换 解题思路 本题的数据规模比较小&#xff0c;暴力法也可以通过。以下将会介绍暴力法和本题最优法。 方法一…

14027.ptp 控制流

文章目录 1 ptp 控制流1.1 控制流分层 1 ptp 控制流 1.1 控制流分层 大体分为4层&#xff1a;1 ptp4l层&#xff1a; 获取配置文件、创建时钟、poll监控文件描述符。2 clock时钟层&#xff1a;提供提供clock_poll、clock_create、clock_sync 等3 port 端口层&#xff1a;port…

通过 GScan 工具自动排查后门

一、简介 GScan 是一款为安全应急响应提供便利的工具&#xff0c;自动化监测系统中常见位置。 工具运行环境&#xff1a;CentOS (6、7) python (2.x、3.x) 工具检查项目&#xff1a; 1、主机信息获取 2、系统初始化 alias 检查 3、文件类安全扫描 3.1、系统重要文件完整行…

JFinal项目搭建

JFinal项目搭建 JFinal项目搭建 JFinal项目搭建 首先创建maven项目&#xff1a; 删掉报错的jsp页面&#xff1a; 在pom.xml中加入坐标&#xff1a; <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-undertow</artifactId>…

零基础学习【Mybatis Plus】这一篇就够了

学习目录 1. 快速入门1-1. 常用注解总结 1-2. 常用配置 2. 核心功能3. 扩展功能4. 插件功能 1. 快速入门 1-1. 常用注解 MybatisPlus中比较常用的几个注解如下&#xff1a; TableName: 用来指定表名Tableld: 用来指定表中的主键字段信息TableField: 用来指定表中的普通字段信…

基于openssl v3搭建ssl安全加固的c++ tcpserver

1 概述 tcp server和tcp client同时使用openssl库&#xff0c;可对通信双方流通的字节序列进行加解密&#xff0c;保障通信的安全。本文以c编写的tcp server和tcp client为例子&#xff0c;openssl的版本为v3。 2 安装openssl v3 2.1 安装 perl-IPC-Cmd openssl项目中的co…

AR 自回归模型

文章目录 总的代码ADF 检验(是否平稳)差分操作拟合AR 模型预测可视化总的代码 import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.tsa.ar_model import AutoReg from statsmodels.tsa.stattools import adfuller# 生成一个示例时间序…

在人工智能时代,如何利用AI达到行业领先地位?

人工智能很快将成为企业开展业务的一个必要环节。各企业都会具备AI战略&#xff0c;就像其具有社交媒体战略、品牌战略和人才战略等一样。 因此&#xff0c;如果企业希望在竞争中脱颖而出、获得优势&#xff0c;不能只是使用AI&#xff0c;而是要以AI为先导&#xff0c;创造行业…

基于springboot+vue的海滨体育馆管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

邮件服务支持Exchange协议,资产历史账号支持设置保留数量,JumpServer堡垒机v3.10.2 LTS版本发布

2024年1月22日&#xff0c;JumpServer开源堡垒机正式发布v3.10.2 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和维护&#xff0c;并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS版本&#xff0c;以获得更佳的使用体验。 在v3.10.2 LTS版本中&…

04 经典的OSPF

思维导图的方式回顾OSPF 什么是OSPF?为什么需要OSPF? - 华为 (huawei.com) 1 ospf 领行学习思维导图 1.1 ospf 的工作过程 建立领据表同步数据库计算路由表1.2 ospf 的状态

用JavaFX写了一个简易的管理系统

文章目录 前言正文一、最终效果1.1 主页面1.2 动物管理页面-初始化1.3 动物管理页面-修改&新增1.4 动物管理页面-删除&批量删除 二、核心代码展示2.1 启动类2.2 数据库配置-db.setting2.3 日志文本域组件2.4 自定义表格视图组件2.5 自定义分页组件2.6 动物管理页面2.7 …

MySQL怎么根据当前时间获取连续十二个月统计数据

需求 在某些业务场景中&#xff0c;需要后台获取连续十二个月的统计数据&#xff0c;如下图&#xff1a; 解决方式 1、创建一张临时表&#xff0c;在表中插入序号数据 该表的最大数量决定统计返回的最大条数 CREATE TABLE sys_redundancy (id bigint(22) NOT NULL AUTO_I…