首页 虚拟现实

Java集合面试通关:List与Set核心考点深度剖析

分类:虚拟现实
字数: (3395)
阅读: (1381)
内容摘要:Java集合面试通关:List与Set核心考点深度剖析,

作为一名 Java 后端工程师,在面试中被问到 Java 集合那是家常便饭。特别是 ListSet,简直是面试官的必考点。但很多同学对它们的理解仅仅停留在“List 有序可重复,Set 无序不重复”这种浅显的层面,一旦深入问一些底层原理、使用场景、以及容易踩坑的地方,就很容易露怯。本文就来帮你彻底搞懂 ListSet,让你在面试中游刃有余。

List:有序可重复,但背后的故事你了解吗?

场景重现:微信朋友圈点赞

想象一下微信朋友圈的点赞功能。点赞列表就是一个典型的 List 应用场景,用户点赞的顺序会被记录下来,并且同一个用户可以多次点赞(虽然实际情况不太可能)。

底层原理:ArrayList vs LinkedList

List 接口最常用的两个实现类是 ArrayListLinkedList。它们的底层实现完全不同,这决定了它们各自的特性和适用场景。

Java集合面试通关:List与Set核心考点深度剖析
  • ArrayList:

    • 底层基于动态数组实现。可以把它想象成一个可以自动扩容的数组。
    • 优点:随机访问效率高(通过下标直接定位元素),因为数组在内存中是连续存储的。
    • 缺点:插入和删除元素效率低(特别是头部或中间位置),因为需要移动元素。
    • 扩容机制:当元素数量超过容量时,会创建一个更大的数组,并将原数组中的元素复制过去。默认扩容为原来的 1.5 倍。
  • LinkedList:

    Java集合面试通关:List与Set核心考点深度剖析
    • 底层基于双向链表实现。可以把它想象成一串互相连接的珠子。
    • 优点:插入和删除元素效率高(只需要修改指针),不需要移动元素。
    • 缺点:随机访问效率低(需要从头或尾部遍历链表),因为链表在内存中不是连续存储的。

代码示例:ArrayList 的常见操作

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建 ArrayList
        List<String> names = new ArrayList<>();

        // 添加元素
        names.add("张三");
        names.add("李四");
        names.add("王五");
        names.add("张三"); // 允许重复元素

        // 获取元素
        String name = names.get(0); // 获取第一个元素
        System.out.println("第一个元素:" + name);

        // 修改元素
        names.set(0, "赵六"); // 将第一个元素修改为赵六
        System.out.println("修改后的第一个元素:" + names.get(0));

        // 删除元素
        names.remove(2); // 删除第三个元素

        // 遍历元素
        for (String n : names) {
            System.out.println(n);
        }
    }
}

实战避坑:ArrayList 的线程安全问题

ArrayList 不是线程安全的。在多线程环境下,多个线程同时修改 ArrayList 可能会导致数据不一致。可以使用 Collections.synchronizedList() 方法将 ArrayList 包装成线程安全的 List,或者使用 CopyOnWriteArrayListCopyOnWriteArrayList 的特点是读写分离,写操作会复制一个新的数组,避免读写冲突,但写操作的开销较大。

Set:无序不重复,靠什么保证唯一性?

场景重现:抽奖系统

设想一个抽奖系统,每个用户只能中奖一次。中奖用户列表就可以使用 Set 来存储,保证每个用户只会被记录一次。

Java集合面试通关:List与Set核心考点深度剖析

底层原理:HashSet vs TreeSet

Set 接口常用的实现类有 HashSetTreeSet。它们对“无序”和“不重复”的实现方式不同。

  • HashSet:

    Java集合面试通关:List与Set核心考点深度剖析
    • 底层基于 HashMap 实现。HashSet 中的元素作为 HashMap 的 key 存储,value 是一个固定的 Object 对象。
    • 无序性:元素的存储位置取决于元素的哈希值,所以看起来是无序的。
    • 唯一性:通过 hashCode()equals() 方法来保证元素的唯一性。如果两个元素的 hashCode() 值不同,则认为是不同的元素;如果 hashCode() 值相同,则继续使用 equals() 方法进行比较,如果 equals() 方法返回 true,则认为是相同的元素,否则认为是不同的元素。
  • TreeSet:

    • 底层基于红黑树(一种自平衡的二叉搜索树)实现。
    • 有序性:元素按照自然顺序或自定义比较器进行排序。
    • 唯一性:通过比较器(自然顺序或自定义比较器)来保证元素的唯一性。如果两个元素的比较结果为 0,则认为是相同的元素。

代码示例:HashSet 的常见操作

import java.util.HashSet;
import java.util.Set;

public class HashSetExample {
    public static void main(String[] args) {
        // 创建 HashSet
        Set<String> uniqueNames = new HashSet<>();

        // 添加元素
        uniqueNames.add("张三");
        uniqueNames.add("李四");
        uniqueNames.add("王五");
        uniqueNames.add("张三"); // 重复元素,不会被添加

        // 打印元素
        System.out.println(uniqueNames); // 输出结果:[张三, 李四, 王五] (顺序不保证)

        // 检查元素是否存在
        boolean contains = uniqueNames.contains("李四");
        System.out.println("是否包含李四:" + contains);

        // 删除元素
        uniqueNames.remove("李四");

        // 遍历元素
        for (String name : uniqueNames) {
            System.out.println(name);
        }
    }
}

实战避坑:重写 hashCode() 和 equals() 方法

如果自定义对象需要存储到 HashSet 中,务必重写 hashCode()equals() 方法,以保证对象的唯一性。重写时需要遵循以下原则:

  • 如果两个对象相等(equals() 返回 true),则它们的 hashCode() 值必须相等。
  • 如果两个对象不相等(equals() 返回 false),则它们的 hashCode() 值最好不相等(可以提高性能)。

可以使用 IDE 自动生成 hashCode()equals() 方法,并根据对象的关键属性进行比较。

List + Set 组合使用:更灵活的应用场景

ListSet 可以结合使用,解决更复杂的问题。例如,可以使用 LinkedHashSet 来实现一个既保证元素唯一性,又保持插入顺序的集合。

在实际项目中,根据具体的业务需求选择合适的 ListSet 实现类,才能充分发挥它们的优势,提高代码的性能和可维护性。 掌握 Java 集合 的核心知识,是成为一名优秀的 Java 后端工程师的必备技能。

Java集合面试通关:List与Set核心考点深度剖析

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea2.store/blog/798102.SHTML

本文最后 发布于2026-04-06 13:46:00,已经过了21天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 绿茶观察员 5 天前
    HashSet 重写 hashCode 和 equals 方法这个坑,之前踩过,差点搞崩了线上服务,感谢提醒!
  • 背锅侠 1 天前
    ArrayList 和 LinkedList 的底层原理讲得很清晰,配上微信朋友圈点赞的例子,通俗易懂。
  • 追梦人 5 天前
    HashSet 重写 hashCode 和 equals 方法这个坑,之前踩过,差点搞崩了线上服务,感谢提醒!
  • 咸鱼翻身 19 分钟前
    如果能再补充一些关于 ConcurrentHashMap 的内容就更完美了!
  • 工具人 5 天前
    CopyOnWriteArrayList 的使用场景和注意事项也讲到了,赞!