java基础-集合
Java 集合框架是 Java 语言中非常重要和强大的一个部分,它提供了一套性能优良、使用方便的数据结构和算法,用于存储和操作一组对象。
一、集合框架的核心思想
Java 集合框架主要分为两大核心接口:
Collection: 存储单个对象的集合。Map: 存储键值对(Key-Value)对象的集合。
它们的关系可以用下图清晰地表示:
Java 集合框架
├── Collection (单值存储)
│ ├── List (有序、可重复)
│ ├── Set (不可重复)
│ └── Queue (队列)
└── Map (键值对存储)├── HashMap├── LinkedHashMap├── TreeMap└── Hashtable二、Collection 接口
Collection 是所有单值集合的根接口。它有三个主要的子接口:List, Set, 和 Queue。
1. List(列表) - 有序、可重复
特点: 元素有顺序(插入顺序),可以通过索引(下标)访问,允许存储重复元素。
常用实现类:
ArrayList:底层结构: 动态数组。初始为10扩容为1.5倍
特点:
查询快: 实现了
RandomAccess接口,通过索引访问元素极快(O(1))。增删慢: 在列表中间插入或删除元素需要移动后续所有元素,性能较差(O(n))。
使用场景: 最常用的列表,适用于频繁查询、很少在中间进行增删的场景。
LinkedList:底层结构: 双向链表。
特点:
增删快: 在已知位置(尤其是头部和尾部)插入或删除元素很快(O(1))。
查询慢: 需要从头或尾遍历链表来定位元素(O(n))。
同时实现了
List和Deque(双端队列)接口。
使用场景: 适用于需要频繁在头尾进行增删操作,或者需要实现栈、队列等数据结构的场景。
Vector:底层结构: 动态数组(与
ArrayList类似)初始为10扩容为2倍。特点: 线程安全,但性能较差。现在已很少使用,被
ArrayList和Collections.synchronizedList取代。它有一个子类
Stack(栈),同样不推荐使用,应使用Deque接口的实现(如LinkedList)来模拟栈。
2. Set(集) - 不可重复
特点: 不允许存储重复元素(根据
equals和hashCode方法判断)。最多包含一个null元素。常用实现类:
HashSet:底层结构: 基于
HashMap(哈希表)初始为16当容量达到0.75时扩容为2倍。特点:
存取最快: 通过哈希算法实现,查询、插入、删除性能都很好(O(1))。
无序: 不保证元素的迭代顺序。
使用场景: 最常用的 Set,用于快速去重,且不关心元素顺序。
LinkedHashSet:底层结构: 继承自
HashSet,但内部使用链表维护顺序初始为16当容量达到0.75时扩容为2倍。特点: 保持插入顺序。迭代顺序就是元素被插入的顺序。
使用场景: 既需要去重,又希望保留插入顺序的场景。
TreeSet:底层结构: 基于
TreeMap(红黑树)。特点:
元素排序: 元素会按照自然顺序(实现
Comparable接口)或指定的Comparator进行排序。性能稍慢: 增删查操作的时间复杂度为 O(log n)。
使用场景: 需要对元素进行自动排序的场景。
3. Queue(队列) - 先进先出(FIFO)
特点: 专门用于处理“先进先出”的数据结构。
常用实现类:
LinkedList: 也实现了Deque接口,因此可以作为队列使用。PriorityQueue:特点: 优先级队列。元素出队顺序不是 FIFO,而是按照元素的自然顺序或比较器的顺序。
使用场景: 任务调度等需要按优先级处理的场景。
三、Map 接口
Map 存储的是键值对(Key-Value),Key 不允许重复(每个 Key 最多映射到一个 Value)。
常用实现类:
HashMap:底层结构: 数组 + 链表 / 红黑树(JDK 1.8 之后)初始为16当容量达到0.75时扩容为2倍。
特点:
存取高效: 基于哈希表,性能最好。
无序: 不保证键值对的顺序。
允许
null键和null值。非线程安全。
使用场景: 最常用的 Map,适用于绝大多数键值对存储场景。
LinkedHashMap:底层结构: 继承自
HashMap,并维护了一个双向链表来记录插入顺序或访问顺序初始为16当容量达到0.75时扩容为2倍。特点: 保持插入顺序或访问顺序。
使用场景: 需要保持 Map 的迭代顺序与插入顺序一致,或用于实现 LRU(最近最少使用)缓存。
TreeMap:底层结构: 红黑树。
特点: 键(Key)是有序的(按自然顺序或自定义比较器排序)。
使用场景: 需要按键的顺序进行遍历的场景。
Hashtable:特点: 线程安全,但性能低下。是遗留类初始为11当容量达到0.75时扩容为2倍+1。
不允许
null键和null值。已被
ConcurrentHashMap(初始为16当容量达到0.75时扩容为2倍)取代,不推荐使用。
四、重要知识点和最佳实践
迭代器(Iterator): 提供了遍历集合的统一方式。
Collections工具类: 提供了大量静态方法,用于对集合进行排序、查找、同步化(如Collections.synchronizedList(list))等操作。Arrays.asList(): 将数组转换为 List,但返回的 List 是固定大小的,不能增删。泛型(Generics): 集合必须使用泛型来指定存储的元素类型,以保证类型安全。
// 正确示例:使用泛型 List<String> list = new ArrayList<>(); list.add("Hello"); // list.add(123); // 编译错误!线程安全:
Vector,Hashtable是线程安全的,但性能差,不推荐。大多数集合(
ArrayList,HashMap等)都是非线程安全的。在多线程环境下,可以使用:
java.util.concurrent包下的类,如ConcurrentHashMap,CopyOnWriteArrayList。使用
Collections.synchronizedXXX()方法包装集合。
equals()和hashCode():当把对象放入
HashSet,或作为HashMap的 Key 时,必须正确重写该对象的equals()和hashCode()方法。重写
equals()必须重写hashCode(),并且要遵守约定:如果两个对象equals()为true,它们的hashCode()必须相等。
