Java-集合框架

本文深入探讨了Java集合框架的不同数据结构,包括ArrayList、LinkedList、HashMap等,对比了它们的特点和适用场景,详细解析了HashMap的工作原理,以及其在JDK1.8前后的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arraylist 与 LinkedList 异同

  1. ArrayList使用的是数组,LinkedList使用的是双向链表。
  2. 二者都是不同步的,也就是不保证线程安全。
  3. ArrayList实现了RandomAccess接口(该接口内什么都没定义,只是一个标识,说明实现了该接口的类可以随机访问),支持快速随机访问(get(int index)),LinkedList不支持。

ArrayList与Vector区别

  1. ArrayList是不同步的,线程不安全,Vector同步,线程安全。
  2. Vector包含许多传统方法,这些方法不属于集合框架。

HashMap

底层实现

JDK1.8之前
JDK1.8之前使用数组加链表实现的,也就是链表散列。将key的hashCode经过扰动函数处理得到hash值,然后通过(n-1) & hash判断存储的位置(n是数组长度),如果该位置没有存放元素,就放在这里。如果该位置存放元素,判断该位置的元素和要存放的元素的key是否一样,如果一样,直接覆盖,否则,用拉链法解决冲突。

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

长度为什么是2的幂次方

为了减少碰撞,尽量把数据分配均匀。hash值大概有40亿映射空间,但内存是放不下的,所以要对数组的长度取模运算,也就是hash % length,计算机中直接求余效率不如位移运算,所以优化为(length-1) & hash(前提是length是2 的幂次方)。

为什么该算法可以减少碰撞呢
2的n次方实际就是1后面n个0,2的n次方-1 实际就是n个1。
例如长度为9时候,3&(9-1)=0 2&(9-1)=0 ,都在0上,碰撞了。
例如长度为8时候,3&(8-1)=3 2&(8-1)=2 ,不同位置上,不碰撞。

线程不安全

HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。多线程会造成死循环问题。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者ConcurrentHashMap。

HashMap 和 Hashtable 的区别

HashTable基本淘汰,不要使用

  1. HashMap是非线程安全的,HashTable是线程安全的,因为内部方法使用了synchronized修饰。
  2. HashMap效率比HashTable高一些。
  3. HashMap中可以有一个键为null,可以有多个键的值为null。HashTable中key和value都不能为null。
  4. 创建时如果不指定容量初始值,Hashtable 默认的初始大小为11,之后每次扩充,容量变为原来的2n+1。HashMap 默认的初始化大小为16。之后每次扩充,容量变为原来的2倍。
  5. 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而HashMap 会将其扩充为2的幂次方大小。
  6. JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

HashSet 和 HashMap 区别

HashSet 底层就是基于 HashMap 实现的

  1. HashMap实现了Map接口,HashSet实现了Set接口。
  2. HashMap储存键值对,HashSet仅仅存储对象。
  3. 使用put()方法将元素放入map中,使用add()方法将元素放入set中。
  4. HashMap中使用键(key)来计算hashcode值,HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false。
  5. HashMap比较快,因为是使用唯一的键来获取对象,HashSet较HashMap来说比较慢。

集合框架底层数据结构总结

Collection

1. List

  • ArrayList: Object数组。
  • Vector: Object数组。
  • LinkedList: 双向链表。

2. Set

  • HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素。
  • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)。

Map

  • HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
  • HashTable: 线程安全(利用synchronized修饰)。数组+链表组成的,数组是 HashTable 的主体,链表则是主要为了解决哈希冲突而存在的。
  • TreeMap: 红黑树(自平衡的排序二叉树)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值