引用:(代码随想录的八股转免费了)以下为网址
本文为学习以上文章的笔记,如果有时间推荐直接去原网址

Sting 导图

List导图

ArrayList 和 Array 有什么区别?ArrayList 和 LinkedList 的区别是什么?(考点:底层数据结构、性能差异)【简单】
ArrayList 和 Array 的区别:
- 类型:
Array是Java中的一个基本数据结构,可以存储基本类型数据或对象引用。ArrayList是Java集合框架中的一个类,实现了List接口,只能存储对象引用。
- 大小可变性:
Array的大小在创建时确定,一旦创建就无法改变。ArrayList的大小是动态的,可以根据需要自动扩容。
- 性能:
- 访问元素时,
Array通常比ArrayList快,因为Array直接通过索引访问。 ArrayList在添加或删除元素时可能更高效,尤其是在数组末尾操作时。
- 访问元素时,
- 泛型支持:
Array可以是泛型的,也可以不是。ArrayList必须是泛型的,提供了类型安全。
- 方法:
Array提供的操作比较有限,主要是基本的数据访问和修改。ArrayList提供了更多的方法,如添加、删除、迭代等。
ArrayList 和 LinkedList 的区别:
- 数据结构:
ArrayList是基于动态数组实现的,适合随机访问。LinkedList是基于双向链表实现的,适合插入和删除操作。
- 性能:
ArrayList在随机访问元素时更快,因为它是通过索引直接访问。LinkedList在插入和删除元素时更快,因为它不需要移动其他元素。
- 内存占用:
ArrayList由于是基于数组,它在存储大量元素时可能会更高效。LinkedList每个元素都需要额外的内存空间来存储前驱和后继元素的引用。
- 扩容:
ArrayList在元素数量达到容量时需要扩容,这个过程涉及到创建新数组和复制旧数组元素。LinkedList不需要扩容,因为它通过链接节点来增加元素。
- 功能:
ArrayList提供了更快的随机访问和更高效的内存使用。LinkedList提供了更高效的插入和删除操作,并且可以更有效地实现栈和队列等数据结构。
在选择ArrayList还是LinkedList时,应该根据具体的应用场景和性能需求来决定。如果频繁进行随机访问操作,ArrayList是更好的选择;如果频繁进行插入和删除操作,LinkedList可能更合适。
ArrayList 和 Array 和 LinkedList 的区别:
Array基本数据结构,可以存储基本类型数据或对象引用。
创建时确定,创建就无法改变
访问元素时,
Array快,Array直接索引访问。可以是泛型的
主要是基本的数据访问和修改
ArrayListJava集合框架中的一个类,实现了
List接口,只能存储对象引用。是动态的,根据需要自动扩容
ArrayList在添加或删除元素时可能更高效,尤其是在数组末尾操作时。必须是泛型
更多的方法,如添加、删除、迭代等
LinkedList
HashSet是如何保证元素不重复的?(考点:哈希算法、equals和hashCode方法)【简单】
HashSet 是Java集合框架中的一个实现了 Set 接口的类,用于存储不允许重复的元素。HashSet通过以下机制来确保元素的唯一性:
- 基于哈希表实现:
- HashSet内部实际上是通过一个
HashMap来存储元素。每个存储在HashSet中的元素作为HashMap的键(key),对应的值(value)是一个固定的常量对象(通常是一个私有的PRESENT对象)。
- HashSet内部实际上是通过一个
- 使用
hashCode()和equals()方法:hashCode()方法:当向HashSet添加一个元素时,首先调用该元素的hashCode()方法来计算其哈希值。这个哈希值决定了元素在哈希表中的存储位置(即桶的位置)。equals()方法:在确定元素存储位置后,HashSet会检查该位置是否已经存在一个具有相同哈希值的元素。如果存在,会调用该元素的equals()方法来判断两个元素是否相等。如果两个元素相等,则认为该元素已经存在,添加操作失败;否则,元素被添加到哈希表中。
- 避免重复:
- 通过上述的
hashCode()和equals()方法,HashSet可以快速检测和防止重复元素的添加,确保每个元素在Set中是唯一的。
- 通过上述的
存储不允许重复的元素
基于哈希表实现:
HashMap来存储元素存储在HashSet中的元素作为键(key),值(value)是一个固定的常量对象
hashCode()方法:添加元素,首先调用hashCode()计算其哈希值。哈希值决定了元素在哈希表中的存储位置(即桶的位置)。
equals()方法:在确定元素存储位置后,HashSet会检查该位置是否已经存在一个具有相同哈希值的元素。如果存在,会调用该元素的equals()方法来判断两个元素是否相等。如果两个元素相等,则认为该元素已经存在,添加操作失败;否则,元素被添加到哈希表中。
List接口和Set接口的区别是什么?(考点:接口特性、集合类型)【简单】
- 1、是否允许元素重复
- 2、是否保证元素的插入顺序
- 3、元素位置访问:
- List提供了按照索引访问元素的方法,如:get(),Set没有提供这样的方法
元素重复:list可以
插入顺序:set不保证
位置访问:List提供索引访问的方法
Java中的HashMap了解吗?HashMap 的底层实现是什么?(考点:底层数据结构)【简单】
HashMap存储数据采用了哈希表的结构,底层使用 一维数组+单向链表+红黑树 进行key-value数据的存储
- 红黑树出现的时机:当某个索引位置i上的链表的长度达到8,且数组的长度超过64时,此索引位置上的元素要从单向链表改为红黑树。--->原因:红黑树进行put()/get()/remove()操作的时间复杂度时o(logn),比单向链表的时间复杂度o(n)好。
- 红黑树退化成单向链表:如果索引i位置是红黑树的结构,当不断删除元素的情况下,当前索引i位置上的元素的个数低于6时,要从红黑树改为单向链表。

HashMap存储数据
哈希表结构
底层使用 一维数组+单向链表+红黑树 进行key-value数据的存储
- 红黑树出现的时机:当某个索引位置i上的链表的长度达到8,且数组的长度超过64时,单向链表改为红黑树。------------>原因:时间复杂度好。
- 红黑树退化成单向链表:当前索引i位置上的元素的个数低于6时,要从红黑树改为单向链表
HashMap 的扩容机制是怎样的?(考点:数组复制、内存分配)【简单】
简单来说,HashMap 的扩容机制是这样的:
-
触发条件: 当
HashMap中存储的键值对数量(size)超过了一个阈值时,就会触发扩容。这个阈值通常是当前容量 * 加载因子(loadFactor,默认0.75)。 -
扩容过程:
- 创建新数组: 创建一个新的、更大的数组,通常是原数组容量的两倍。
- 重新计算哈希与迁移 (Rehashing): 遍历旧数组中的每一个键值对,重新计算它们在新数组中的位置(因为数组长度变了,哈希映射的索引也会变),然后将它们放入新数组的对应位置。这个过程很重要,因为同一个元素在新旧数组中的桶(bucket)索引很可能不同。
-
目的:
- 减少哈希冲突: 通过扩大数组容量,使得键值对能更均匀地分布,从而减少哈希冲突,保持
HashMap的查找、插入等操作的效率(接近 O(1))。 - 保持性能: 如果不扩容,当元素越来越多时,链表(或红黑树)会越来越长,性能会下降。
- 减少哈希冲突: 通过扩大数组容量,使得键值对能更均匀地分布,从而减少哈希冲突,保持
简单讲就是:装不下了(或快装不下了,为了性能) -> 造个更大的新家 -> 把旧家里的东西重新摆放到新家里。
简单来说,
HashMap的扩容机制是这样的:
触发条件: 当
HashMap中存储的键值对数量(size)超过了一个阈值时,就会触发扩容。这个阈值通常是当前容量 * 加载因子(loadFactor,默认0.75)。扩容过程:
- 创建新数组: 创建新的、更大的数组,两倍。
- 重新计算哈希与迁移 (Rehashing): 遍历每一个键值对,重新计算位置,放入对应位置
目的:
- 减少哈希冲突: 更均匀地分布,从而减少哈希冲突,保持
HashMap的查找、插入等操作的效率(接近 O(1))。- 保持性能: 如果不扩容,当元素越来越多时,链表(或红黑树)会越来越长,性能会下降。
简单讲就是:装不下了(或快装不下了,为了性能) -> 造个更大的新家 -> 把旧家里的东西重新摆放到新家里。
TreeMap和HashMap的区别是什么?(考点:底层数据结构、排序特性)【简单】
- 实现原理:
- HashMap基于hash表实现,计算键的hash值来确定存储位置。默认情况下,hashmap不保证元素的存储顺序,从java8之后,h链表过长会转化为红黑树
- TreeMap基于红黑树实现,是一种自平衡二叉查找树,能够保持键的有序性,因此,TreeMap中的元素总是按照键的自然顺序或者创建时提供的Comparator进行排序。
- 性能特点:
- HashMap查找、插入、删除的平均复杂度均为O(1)
- TreeMap查找、插入、删除的时间复杂度均为O(logn)
- 实现原理:
- HashMap基于hash表实现,计算键的hash值来确定存储位置。不保证元素的存储顺序,链表过长会转化为红黑树
- TreeMap基于红黑树实现,是自平衡二叉查找树,保持键的有序性,TreeMap中的元素总是按照键的自然顺序或者创建时提供的Comparator进行排序。
- 性能特点:
- HashMap平均复杂度均为O(1)
- TreeMap时间复杂度均为O(logn)
HashSet 和 HashMap 的区别?(考点:底层数据结构)【简单】
-
存储内容不同:
HashSet:存储的是不重复的单个元素(对象)。它主要用来快速检查某个元素是否存在于集合中。HashMap:存储的是键值对 (Key-Value pairs)。它用来根据键快速查找对应的值。
-
内部实现关系:
HashSet内部实际上是基于HashMap实现的。当你向HashSet添加一个元素时,这个元素会作为HashMap的键 (Key),而对应的值 (Value) 则是一个固定的虚拟对象 (dummy Object)。
简单说:
-
HashSet就像一个只有“物品清单”的集合,只关心物品本身在不在。 -
HashMap像一个“字典”或“名册”,每个“词条”(键)都有对应的“解释”(值)。
所以,如果你只需要存储一堆不重复的东西,用 HashSet;如果你需要给这些东西关联额外的信息,用 HashMap。
存储内容不同:
HashSet:不重复的单个元素(对象)。快速检查某个元素是否存在于集合中。HashMap:键值对 (Key-Value pairs)。根据键快速查找对应的值。内部实现关系:
HashSet内部实际上是基于HashMap实现的。当你向HashSet添加一个元素时,这个元素会作为HashMap的键 (Key),而对应的值 (Value) 则是一个固定的虚拟对象 (dummy Object)。简单说:
HashSet就像一个只有“物品清单”的集合,只关心物品本身在不在。
HashMap像一个“字典”或“名册”,每个“词条”(键)都有对应的“解释”(值)。只需要存储一堆不重复的东西,用
HashSet;需要给这些东西关联额外的信息,用
HashMap。
HashMap 和 HashTable 的区别?(考点:底层数据结构)【简单】
简要回答 HashMap 和 Hashtable 的主要区别:
-
线程安全性:
HashMap:非线程安全。Hashtable:线程安全。它的方法大多是synchronized的,并发性能较低。
-
null 键和 null 值:
HashMap:允许一个null键和多个null值。Hashtable:不允许null键,也不允许null值(会抛出NullPointerException)。
-
性能:
HashMap:由于非线程安全,单线程下性能通常比Hashtable好。Hashtable:由于方法同步,多线程开销较大,性能通常较低。在需要线程安全的场景下,更推荐使用ConcurrentHashMap。
-
父类:
HashMap:继承自AbstractMap类。Hashtable:继承自Dictionary类(一个比较老的类)。
总结: Hashtable 是一个遗留的线程安全类,性能较差。如果需要线程安全,推荐使用 ConcurrentHashMap。如果不需要线程安全,使用 HashMap。
简要回答
HashMap和Hashtable的主要区别:
线程安全性:
HashMap:非线程安全。Hashtable:线程安全。它的方法大多是synchronized的,并发性能较低。null 键和 null 值:
HashMap:允许一个null键和多个null值。Hashtable:不允许null键,也不允许null值(会抛出NullPointerException)。性能:
HashMap:由于非线程安全,单线程下性能好。Hashtable:由于方法同步,多线程开销较大,性能通常较低。在需要线程安全的场景下,更推荐使用ConcurrentHashMap。父类:
HashMap:继承自AbstractMap类。Hashtable:继承自Dictionary类(一个比较老的类)。总结:
Hashtable是一个遗留的线程安全类,性能较差。如果需要线程安全,推荐使用ConcurrentHashMap。如果不需要线程安全,使用HashMap。
Java的集合类有哪些,那些是线程安全的,那些是线程不安全的?(考点:线程安全)【简单】
Java的集合类
Java的集合主要是由Map和Collection这两个接口派生出来的。Collection接口又派生出三个重要的接口Set, List, Queue。
Java所有的集合类,都是Set, List,Map, Queue这几个接口的实现类。
- Set接口:Set接口的主要实现类有:HashSet, TreeSet, LinkedHashSet。Set集合最大的特征就是不允许存储重复的元素。
- List接口:List接口的主要实现类有:ArrayList, LinkedList。List接口里面存储的元素是有序的,并且允许存放重复的元素。
- Map接口: Map接口的主要实现类有:HashMap,TreeMap, LinkedHashMap。Map接口存放的就是键值对。
- Queue接口: Queue接口的主要实现类有:ArrayDeque, PriorityQueue。Queue接口主要是用来实现队列的。
线程安全集合类
- Vector:这个和ArrayList类比较像,只不过Vector中的每个方法都被synchronized关键字修饰,所以Vector集合是线程安全的。
- HashTable:这个和HashMap类比较像,同样的HashTable中的每个方法都被synchronized关键字修饰。
java.util.concurrent 包提供的都是线程安全的集合:
- ConcurrentHashMap: ConcurrentHashMap通过锁分离技术实现了线程安全。
线程不安全集合类
ArrayList,LinkedList, HashSet,HashMap,TreeSet,TreeMap 这些类都是线程不安全的集合类,只能在单线程环境下使用,在多线程环境下,如果没有合适的同步措施,就会造成数据不一致等并发问题。
HashMap 为什么是线程不安全的? 如何实现线程安全?(考点:线程安全、底层数据结构)【中等】
- HashMap是不安全的,主要是因为HashMap内部在多线程并发访问的时候,没有进行同步处理,所以在是线程不安全的
- 实现HashMap的线程安全有以下几种方法:
- 调用Collections.syncronizedMap()方法来实现线程安全,会对所有方法调用加锁,确保同一时刻只有一个线程能够访问集合对象
- 使用线程安全的集合类,如ConcurrentHashMap类,就是线程安全的
Collection接口和Collections类的区别是什么?(考点:接口与类的区别、工具类作用)【简单】
-
collection是一个接口,是java集合框架的根接口之一
-
collections是一个工具类,包含了很多操作集合的静态方法
Vector和ArrayList的区别是什么?(考点:线程安全、性能差异)【简单】
- 线程安全性:
- Vector是线程安全的,他的每个方法都被声明为synchronized,多线程环境下可以直接使用不需要额外开销
- ArrayList不是线程安全的
- 性能:
- Vector由于所有公开的方法都是同步的,所以性能可能不如ArrayList
- 扩容机制:
- Vector容量不足的情况下,会扩容至两倍
- ArrayList容量不足的情况下,通常会扩容1.5倍
1417

被折叠的 条评论
为什么被折叠?



