文章目录
一、Java 集合框架概览
Java 集合框架的两大根接口:
java.util.Collection:List、Set、Queue 的共同父接口(不包括 Map)。java.util.Map:键值对集合,单独体系。
主要接口与常见实现:
List:ArrayList、LinkedList、CopyOnWriteArrayListSet:HashSet、LinkedHashSet、TreeSetQueue/Deque:PriorityQueue、ArrayDeque、LinkedListMap:HashMap、LinkedHashMap、TreeMap、ConcurrentHashMap
辅助工具类:
Collections(工具静态方法,如排序、线程安全包装)Arrays(数组与集合互转)Objects(空值检查等)
关键点:
List有序且可重复;Set无重复;Map键唯一。Hash*系列依赖hashCode()与equals(),Tree*系列依赖比较器(Comparable或Comparator)。- 并发场景使用
java.util.concurrent包下的集合。
二、复杂度与选型
| 操作 / 集合 | ArrayList | LinkedList | HashSet / HashMap | TreeSet / TreeMap | LinkedHashMap |
|---|---|---|---|---|---|
| 随机访问 get(i) | O(1) | O(n) | — | — | — |
| 插入(末尾) | O(1) 摊销 | O(1) | O(1) 摊销 | O(log n) | O(1) 摊销 |
| 插入(中间) | O(n) | O(1) (在已获节点处) | O(1) | O(log n) | O(1) |
| 删除(指定位置) | O(n) | O(1)(在已获节点处) | O(1) | O(log n) | O(1) |
| 查找 contains / get by key | O(n) | O(n) | O(1) | O(log n) | O(1) |
| 保持顺序 | 可 | 可 | 否(LinkedHashSet 保证插入顺序) | 排序顺序 | 保证插入顺序或访问顺序 |
三、概念详解
1. equals() 与 hashCode()
在哈希集合/映射中,判断元素是否相等依赖于 equals() 和 hashCode()。必须满足:
- 如果
a.equals(b)为true,则a.hashCode() == b.hashCode()。 - 如果
a.hashCode() == b.hashCode(),equals不一定为true(哈希冲突允许)。
自定义 Book 的 equals/hashCode:
public class Book {
private final String isbn;
private final String title;
private final String author;
public Book(String isbn, String title, String author) {
this.isbn = isbn;
this.title = title;
this.author = author;
}
// 仅以 ISBN 作为唯一标识
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book b = (Book) o;
return isbn != null && isbn.equals(b.isbn);
}
@Override
public int hashCode() {
return isbn == null ? 0 : isbn.hashCode();
}
@Override
public String toString() {
return String.format("Book{isbn='%s', title='%s', author='%s'}", isbn, title, author);
}
}
2. Comparator 与 Comparable
Comparable<T>:自然顺序(类内部实现compareTo)。Comparator<T>:外部排序策略(常用于灵活排序)。
示例:按书名排序的比较器:
Comparator<Book> byTitle = Comparator.comparing(book -> book.getTitle());
使用 TreeSet(按 title 排序):
Set<Book> treeSetByTitle = new TreeSet<>(Comparator.comparing(Book::getTitle));
treeSetByTitle.addAll(listOfBooks);
3. List:ArrayList vs LinkedList
ArrayList:大多数场景首选(随机访问快、内存连续)。插入/删除中间元素代价高。LinkedList:在需要频繁在头/中间插入且已有节点引用时可用(但很少优于 ArrayList)。
遍历推荐使用增强 for 或迭代器(Iterator),若需要并发修改使用 ListIterator 的 remove()/add()。
4. Set:HashSet / LinkedHashSet / TreeSet
HashSet:无序,最快的去重容器。LinkedHashSet:保持插入顺序,适合需要顺序与去重的场景。TreeSet:有序集合(红黑树),支持范围操作(subSet、headSet等)。
5. Map:HashMap / LinkedHashMap / TreeMap / ConcurrentHashMap
HashMap:常用,不线程安全。LinkedHashMap:可保持插入或访问顺序(可用于实现 LRU 缓存)。TreeMap:基于红黑树的有序映射。ConcurrentHashMap:高并发读写场景首选。
使用 LinkedHashMap 实现简单 LRU(重写 removeEldestEntry):
Map<K,V> lru = new LinkedHashMap<K,V>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return size() > MAX_ENTRIES;
}
};
四、常用 API
1. Collections 工具类
- 排序:
Collections.sort(list)(对于自定义对象可传 Comparator) - 线程安全包装:
Collections.synchronizedList(list)(注意仍需在迭代时手动同步) - 不可变集合:
Collections.unmodifiableList(list)(原始 list 改变会影响不可变视图) - 二分查找:
Collections.binarySearch(list, key, comparator)
安全迭代 synchronizedList:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
synchronized (syncList) {
for (String s : syncList) {
// safe
}
}
2. Arrays 与集合转换
String[] arr = {"a","b"};
List<String> list = Arrays.asList(arr); // 固定大小的 List(不能 add/remove)
List<String> arrayList = new ArrayList<>(Arrays.asList(arr)); // 可变副本
3. Stream 与集合互操作
List<Book> popularBooks = books.stream()
.filter(b -> b.getRating() >= 4.5)
.sorted(Comparator.comparing(Book::getRating).reversed())
.collect(Collectors.toList());
1万+

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



