Java集合口试总结(标题来源JavaGuide)

打印 上一主题 下一主题

主题 1781|帖子 1781|积分 5343

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题1:说说 List,Set,Map 三者的区别?

在 Java 中,List、Set 和 Map 是最常用的集合框架(Collection Framework)接口,它们的重要区别如下:
1. List(列表)


  • 特点

    • 允许存储 重复元素
    • 保持插入次序,即元素的存储次序与遍历次序同等。
    • 允许null值(可存多个)。
    • 提供索引访问,可以使用索引(get(int index))获取元素。

  • 常见实现类

    • ArrayList(基于数组,查询快,增删慢)
    • LinkedList(基于双向链表,查询慢,增删快)
    • Vector(线程安全的 ArrayList,但性能较低)

  • 使用场景

    • 需要有序存储元素,而且可能有重复值,例如存储一系列日志纪录、待服务项等。


2. Set(集合)


  • 特点

    • 不允许存储重复元素
    • 无法通过索引访问元素(没有 get(int index) 方法)。
    • 默认情况下不包管元素的存储次序(TreeSet 除外)。
    • 允许最多一个 null 值(HashSet 允许,TreeSet 不允许)。

  • 常见实现类

    • HashSet(基于哈希表,存取快,但无序)
    • LinkedHashSet(有序的 HashSet,按插入次序存储)
    • TreeSet(基于红黑树自动排序,不允许 null)

  • 使用场景

    • 需要存储唯一的元素集合,例如存储用户ID、标签等。


3. Map(映射)


  • 特点

    • 键值对 (key-value) 形式存储数据。
    • Key 不可重复,但 Value 可以重复。
    • 允许最多一个 null 键,多值 null 值(TreeMap 不允许 null 键)。

  • 常见实现类

    • HashMap(无序,基于哈希表,存取快,线程不安全)
    • LinkedHashMap(有序的 HashMap,按插入次序存储)
    • TreeMap(排序的 Map,基于红黑树,按 Key 排序)

  • 使用场景

    • 需要存储键值映射,如学生学号-姓名、配置项键值对等。


总结对比
特性ListSetMap是否允许重复元素允许不允许Key 不允许重复,Value 允许是否包管次序包管插入次序HashSet 无序,LinkedHashSet 包管插入次序,TreeSet 排序HashMap 无序,LinkedHashMap 保持插入次序,TreeMap 按 key 排序是否可存 null允许多个仅 HashSet 允许一个HashMap 允许一个 null Key,多 null Value,TreeMap 不允许 null Key访问方式通过索引 (get(int index))迭代器 (Iterator)通过 Key (get(K key))实用场景需要有序存储并允许重复,如购物车、使命列表需要唯一元素,如用户ID需要键值映射,如用户信息 简单影象


  • List 适合 有序、可重复 场景。
  • Set 适合 唯一、无序(或排序) 场景。
  • Map 适合 键值映射 场景。
问题2: List,Set,Map 在 Java 中分别由哪些对应的实现类?底层的数据结构?

在 Java 中,List、Set 和 Map 各自有多个常见的实现类,它们的底层数据结构不同,实用于不同的场景。下面详细分析各自的实现类及其底层结构。

1. List(列表)
List 重要有以下几个实现类:
(1)ArrayList


  • 底层数据结构动态数组
  • 特点

    • 查询速度快(基于数组,通过索引访问,O(1))。
    • 插入和删除慢(涉及数据移动,O(n))。
    • 允许 null 元素,允许重复元素。
    • 线程不安全。

  • 实用场景

    • 读操纵多,写操纵少的场景,如缓存数据、搜索结果等。


(2)LinkedList


  • 底层数据结构双向链表
  • 特点

    • 查询速度慢(链表遍历,O(n))。
    • 插入、删除速度快(O(1),不涉及数据移动)。
    • 允许 null 元素,允许重复元素。
    • 线程不安全。

  • 实用场景

    • 频繁插入、删除元素,如使命队列、消息队列等。


(3)Vector


  • 底层数据结构动态数组
  • 特点

    • 与 ArrayList 类似,但线程安全(方法加了 synchronized)。
    • 查询快,插入删除慢。
    • 允许 null 元素,允许重复元素。

  • 实用场景

    • 多线程情况下,需要线程安全的 List。


2. Set(集合)
Set 重要有以下几个实现类:
(1)HashSet


  • 底层数据结构哈希表(基于 HashMap 实现,值存 HashMap 的 key)
  • 特点

    • 无序存储元素(元素次序可能变革)。
    • 不允许重复元素
    • 允许 null 值(但只能有一个)。
    • 查询、插入、删除速度快(平均 O(1))。

  • 实用场景

    • 需要去重的集合,如存储唯一用户ID。


(2)LinkedHashSet


  • 底层数据结构哈希表 + 双向链表
  • 特点

    • 有序(按照插入次序存储)。
    • 不允许重复元素
    • 查询、插入、删除速度比 HashSet 略慢(受链表影响)。

  • 实用场景

    • 既需要去重,又要保持插入次序的场景,如LRU缓存。


(3)TreeSet


  • 底层数据结构红黑树(自平衡二叉搜索树)
  • 特点

    • 自动排序(默认按升序排序,可自定义 Comparator)。
    • 不允许重复元素
    • 不允许 null
    • 查询、插入、删除速度 O(log n)(比 HashSet 慢)。

  • 实用场景

    • 需要排序且去重的集合,如排行榜、时间排序数据。


3. Map(映射)
Map 重要有以下几个实现类:
(1)HashMap


  • 底层数据结构数组 + 单链表 + 红黑树(JDK 1.8 之后)
  • 特点

    • Key 无序存储,不允许重复,允许 null(最多一个)。
    • Value 允许重复,允许 null。
    • 查询、插入、删除快(O(1),最坏 O(log n))。
    • 线程不安全。

  • 实用场景

    • 需要快速查找 key-value 数据,如缓存、配置项存储。


(2)LinkedHashMap


  • 底层数据结构哈希表 + 双向链表
  • 特点

    • 按插入次序存储(可以用 accessOrder=true 变成 LRU 访问次序)。
    • 查询、插入、删除速度略低于 HashMap(受链表影响)。

  • 实用场景

    • 需要按插入次序遍历的 Map,如缓存实现。


(3)TreeMap


  • 底层数据结构红黑树
  • 特点

    • Key 自动排序(默认升序,可自定义 Comparator)。
    • Key 不允许 null(Value 允许)。
    • 查询、插入、删除 O(log n)。

  • 实用场景

    • 需要按 key 排序的 Map,如时间戳排序的日志数据。


(4)Hashtable


  • 底层数据结构哈希表
  • 特点

    • 线程安全(方法加 synchronized)。
    • 不允许 null key 和 null value
    • 查询、插入、删除 O(1)。
    • 效率较低(同步开销大)。

  • 实用场景

    • 需要线程安全的 Map(但通常用 ConcurrentHashMap 替换)。


(5)ConcurrentHashMap


  • 底层数据结构分段锁 + 哈希表(JDK 1.7),CAS + 哈希表 + 红黑树(JDK 1.8)
  • 特点

    • 线程安全,高效(分段锁 / CAS 机制)。
    • 不允许 null key 和 null value
    • 查询、插入、删除比 Hashtable 快(O(1))。

  • 实用场景

    • 高并发情况下的 Map,如缓存存储。


总结
  类型
  实现类
  底层数据结构
  重要特点
  实用场景
  List
  ArrayList
  动态数组
  查询快,增删慢
  读多写少
  
  LinkedList
  双向链表
  插入/删除快,查询慢
  频繁增删
  
  Vector
  动态数组
  线程安全
  多线程
  Set
  HashSet
  哈希表
  无序,不重复
  唯一集合
  
  LinkedHashSet
  哈希表 + 双向链表
  插入次序
  唯一且有序
  
  TreeSet
  红黑树
  自动排序
  唯一且排序
  Map
  HashMap
  数组 + 链表 + 红黑树
  无序,查询快
  快速查找
  
  LinkedHashMap
  哈希表 + 双向链表
  按插入次序
  LRU缓存
  
  TreeMap
  红黑树
  Key 自动排序
  需要排序
  
  Hashtable
  哈希表
  线程安全,低效
  线程安全(少用)
  
  ConcurrentHashMap
  哈希表 + CAS
  高并发
  并发情况
   问题3:有哪些集合是线程不安全的?怎么办理呢?

1. 线程不安全的集合
(1)ArrayList(线程不安全)


  • 底层数据结构:动态数组
  • 问题:多线程情况下,多个线程同时 add() 可能导致 数据覆盖、数组扩容时的数据丢失
  • 办理方案

    • 使用 Vector(线程安全,但性能较低)
    • 使用 Collections.synchronizedList(new ArrayList<>())
    • 使用 CopyOnWriteArrayList(实用于读多写少的场景)


(2)HashMap(线程不安全)


  • 底层数据结构:数组 + 链表(JDK 1.7),数组 + 链表 + 红黑树(JDK 1.8)
  • 问题

    • JDK 1.7 多线程 put() 时可能引发死循环(rehash 过程中链表反转)。
    • JDK 1.8 仍然是线程不安全的,多线程 put() 可能会丢数据。

  • 办理方案

    • 使用 ConcurrentHashMap(高性能并发 Map,推荐)
    • 使用 Collections.synchronizedMap(new HashMap<>())(性能较低)
    • 使用 Hashtable(线程安全但性能差,较少使用)


2. ArrayList vs. Vector(高频对比)
  对比项
  ArrayList
  Vector
  线程安全
  ❌ 非线程安全
  ✅ 线程安全(synchronized)
  底层数据结构
  动态数组
  动态数组
  扩容方式
  1.5x 扩容
  2x 扩容
  性能
  高(无锁)
  低(同步开销大)
  实用场景
  单线程
  多线程(但 CopyOnWriteArrayList 更推荐)
  
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南飓风

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表