Java集合框架深入与实践
下面我将提供详细的Java集合框架代码示例,涵盖List、Set、Map等核心接口及其实现类,并包含底层原理的模拟实现和高级用法。
1. List接口及其实现类
ArrayList 示例与原理模拟
import java.util.*;
public class ListPractice {
public static void main(String[] args) {
// ArrayList - 基于动态数组
List<String> arrayList = new ArrayList<>();
// 添加元素
arrayList.add("Java");
arrayList.add("Python");
arrayList.add("C++");
arrayList.add(1, "JavaScript"); // 在指定位置插入
System.out.println("ArrayList: " + arrayList);
// 访问元素
System.out.println("第一个元素: " + arrayList.get(0));
System.out.println("包含Java吗? " + arrayList.contains("Java"));
// 修改元素
arrayList.set(2, "Go");
System.out.println("修改后: " + arrayList);
// 删除元素
arrayList.remove("C++");
arrayList.remove(0);
System.out.println("删除后: " + arrayList);
// 遍历
System.out.println("=== 遍历ArrayList ===");
// 1. for循环
for (int i = 0; i < arrayList.size(); i++) {
System.out.println("索引 " + i + ": " + arrayList.get(i));
}
// 2. 增强for循环
for (String language : arrayList) {
System.out.println("语言: " + language);
}
// 3. 迭代器
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
System.out.println("迭代器: " + iterator.next());
}
// 4. forEach方法 (Java 8+)
arrayList.forEach(lang -> System.out.println("forEach: " + lang));
// ArrayList扩容机制演示
demonstrateArrayListResizing();
// LinkedList - 基于双向链表
List<String> linkedList = new LinkedList<>();
linkedList.add("Apple");
linkedList.add("Banana");
linkedList.addFirst("Orange"); // 链表头部添加
linkedList.addLast("Grape"); // 链表尾部添加
System.out.println("LinkedList: " + linkedList);
// LinkedList的特有方法
LinkedList<String> ll = (LinkedList<String>) linkedList;
System.out.println("第一个元素: " + ll.getFirst());
System.out.println("最后一个元素: " + ll.getLast());
ll.removeFirst();
ll.removeLast();
System.out.println("删除首尾后: " + ll);
// Vector - 线程安全的ArrayList (已过时,不推荐使用)
Vector<String> vector = new Vector<>();
vector.add("Element1");
vector.add("Element2");
System.out.println("Vector: " + vector);
}
// 模拟ArrayList的扩容机制
private static void demonstrateArrayListResizing() {
System.out.println("\n=== ArrayList扩容机制演示 ===");
// 创建一个初始容量为3的ArrayList
List<Integer> list = new ArrayList<>(3);
System.out.println("初始容量: 3");
for (int i = 1; i <= 5; i++) {
list.add(i);
// 使用反射获取实际容量(仅供演示,生产环境不推荐)
try {
java.lang.reflect.Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
Object[] elementData = (Object[]) field.get(list);
System.out.println("添加元素 " + i + "后, 大小: " + list.size() +
", 容量: " + elementData.length);
} catch (Exception e) {
System.out.println("无法获取内部数组容量");
}
}
}
}
自定义简化版ArrayList实现
// 自定义简化版ArrayList,理解底层数组实现
class MyArrayList<E> {
private static final int DEFAULT_CAPACITY = 10;
private Object[] elementData;
private int size;
public MyArrayList() {
this.elementData = new Object[DEFAULT_CAPACITY];
}
public MyArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else {
throw new IllegalArgumentException("初始容量必须大于0");
}
}
public void add(E e) {
// 确保容量足够
ensureCapacityInternal(size + 1);
elementData[size++] = e;
}
public void add(int index, E element) {
checkRangeForAdd(index);
ensureCapacityInternal(size + 1);
// 将index及之后的元素向后移动一位
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
@SuppressWarnings("unchecked")
public E get(int index) {
checkRange(index);
return (E) elementData[index];
}
public E remove(int index) {
checkRange(index);
E oldValue = get(index);
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null; // 帮助垃圾回收
return oldValue;
}
public int size() {
return size;
}
private void ensureCapacityInternal(int minCapacity) {
if (minCapacity - elementData.length > 0) {
grow(minCapacity);
}
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 新容量 = 旧容量 * 1.5
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
elementData = Arrays.copyOf(elementData, newCapacity);
System.out.println("扩容: " + oldCapacity + " -> " + newCapacity);
}
private void checkRange(int index) {
if (index >= size || index < 0) {
throw new IndexOutOfBoundsException("索引: " + index + ", 大小: " + size);
}
}
private void checkRangeForAdd(int index) {
if (index > size || index < 0) {
throw new IndexOutOfBoundsException("索引: " + index + ", 大小: " + size);
}
}
@Override
public String toString() {
if (size == 0) {
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append('[');
for (int i = 0; i < size; i++) {
sb.append(elementData[i]);
if (i == size - 1) {
sb.append(']');
} else {
sb.append(',').append(' ');
}
}
return sb.toString();
}
}
public class CustomArrayListDemo {
public static void main(String[] args) {
MyArrayList<String> myList = new MyArrayList<>(3);
myList.add("A");
myList.add("B");
myList.add("C");
System.out.println("初始列表: " + myList);
// 触发扩容
myList.add("D");
System.out.println("扩容后: " + myList);
myList.add(2, "E");
System.out.println("插入后: " + myList);
myList.remove(1);
System.out.println("删除后: " + myList);
System.out.println("索引2的元素: " + myList.get(2));
}
}
2. Set接口及其实现类
import java.util.*;
public class SetPractice {
public static void main(String[] args) {
// HashSet - 基于HashMap,无序
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Orange");
hashSet.add("Apple"); // 重复元素,不会被添加
System.out.println("HashSet: " + hashSet);
System.out.println("包含Apple? " + hashSet.contains("Apple"));
// 遍历HashSet
System.out.println("=== 遍历HashSet ===");
for (String fruit : hashSet) {
System.out.println(fruit);
}
// LinkedHashSet - 维护插入顺序
Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("First");
linkedHashSet.add("Second");
linkedHashSet.add("Third");
linkedHashSet.add("First"); // 重复
System.out.println("LinkedHashSet: " + linkedHashSet);
// TreeSet - 基于TreeMap,有序
Set<String> treeSet = new TreeSet<>();
treeSet.add("Orange");
treeSet.add("Apple");
treeSet.add("Banana");
System.out.println("TreeSet(自然排序): " + treeSet);
// 自定义排序
Set<String> reverseTreeSet = new TreeSet<>(Comparator.reverseOrder());
reverseTreeSet.add("Orange");
reverseTreeSet.add("Apple");
reverseTreeSet.add("Banana");
System.out.println("TreeSet(逆序): " + reverseTreeSet);
// 对象去重示例
demonstrateObjectDeduplication();
}
// 演示对象如何正确实现去重
private static void demonstrateObjectDeduplication() {
System.out.println("\n=== 对象去重演示 ===");
// 未正确实现equals和hashCode的类
Set<BadStudent> badStudents = new HashSet<>();
badStudents.add(new BadStudent(1, "Alice"));
badStudents.add(new BadStudent(1, "Alice")); // 应该去重但不会
System.out.println("BadStudent去重失败: " + badStudents.size());
// 正确实现equals和hashCode的类
Set<GoodStudent> goodStudents = new HashSet<>();
goodStudents.add(new GoodStudent(1, "Alice"));
goodStudents.add(new GoodStudent(1, "Alice")); // 成功去重
System.out.println("GoodStudent成功去重: " + goodStudents.size());
}
}
// 未正确实现equals和hashCode的类
class BadStudent {
private int id;
private String name;
public BadStudent(int id, String name) {
this.id = id;
this.name = name;
}
// 缺少equals和hashCode方法
}
// 正确实现equals和hashCode的类
class GoodStudent {
private int id;
private String name;
public GoodStudent(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GoodStudent that = (GoodStudent) o;
return id == that.id && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
3. Map接口及其实现类
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class MapPractice {
public static void main(String[] args) {
// HashMap - 最常用的Map实现
Map<String, Integer> hashMap = new HashMap<>();
// 添加键值对
hashMap.put("Apple", 10);
hashMap.put("Banana", 5);
hashMap.put("Orange", 8);
hashMap.put("Apple", 15); // 更新已有键的值
System.out.println("HashMap: " + hashMap);
// 访问值
System.out.println("Apple的数量: " + hashMap.get("Apple"));
System.out.println("包含Banana键? " + hashMap.containsKey("Banana"));
System.out.println("包含值10? " + hashMap.containsValue(10));
// 遍历HashMap
System.out.println("=== 遍历HashMap ===");
// 1. 遍历键
for (String key : hashMap.keySet()) {
System.out.println("Key: " + key + ", Value: " + hashMap.get(key));
}
// 2. 遍历值
for (Integer value : hashMap.values()) {
System.out.println("Value: " + value);
}
// 3. 遍历键值对
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
System.out.println("Entry: " + entry.getKey() + " => " + entry.getValue());
}
// 4. forEach方法 (Java 8+)
hashMap.forEach((k, v) -> System.out.println("ForEach: " + k + " => " + v));
// LinkedHashMap - 维护插入顺序
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("Zebra", 1);
linkedHashMap.put("Apple", 2);
linkedHashMap.put("Banana", 3);
System.out.println("LinkedHashMap(插入顺序): " + linkedHashMap);
// 访问顺序的LinkedHashMap (LRU缓存基础)
Map<String, Integer> accessOrderMap = new LinkedHashMap<>(16, 0.75f, true);
accessOrderMap.put("A", 1);
accessOrderMap.put("B", 2);
accessOrderMap.put("C", 3);
// 访问元素B,它会被移动到末尾
accessOrderMap.get("B");
System.out.println("访问顺序LinkedHashMap: " + accessOrderMap);
// TreeMap - 基于红黑树,按键排序
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("Orange", 3);
treeMap.put("Apple", 1);
treeMap.put("Banana", 2);
System.out.println("TreeMap(按键排序): " + treeMap);
// 自定义排序
Map<String, Integer> reverseTreeMap = new TreeMap<>(Comparator.reverseOrder());
reverseTreeMap.put("Orange", 3);
reverseTreeMap.put("Apple", 1);
reverseTreeMap.put("Banana", 2);
System.out.println("TreeMap(逆序): " + reverseTreeMap);
// ConcurrentHashMap - 线程安全的HashMap
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("A", 1);
concurrentMap.put("B", 2);
concurrentMap.put("C", 3);
System.out.println("ConcurrentHashMap: " + concurrentMap);
// HashMap原理演示
demonstrateHashMapMechanism();
}
// 演示HashMap的工作原理
private static void demonstrateHashMapMechanism() {
System.out.println("\n=== HashMap原理演示 ===");
// 创建一个小的HashMap以便观察
Map<String, Integer> smallMap = new HashMap<>(4);
// 添加一些元素,观察哈希冲突
smallMap.put("Aa", 1); // "Aa"和"BB"有相同的哈希值
smallMap.put("BB", 2);
smallMap.put("CC", 3);
smallMap.put("DD", 4);
System.out.println("小HashMap: " + smallMap);
// 使用反射查看内部结构(仅供教学,生产环境不推荐)
try {
java.lang.reflect.Field tableField = HashMap.class.getDeclaredField("table");
tableField.setAccessible(true);
Object[] table = (Object[]) tableField.get(smallMap);
if (table != null) {
System.out.println("哈希表长度: " + table.length);
for (int i = 0; i < table.length; i++) {
if (table[i] != null) {
System.out.println("桶 " + i + ": 有元素");
// 遍历链表/树
java.lang.reflect.Field nextField = table[i].getClass().getDeclaredField("next");
nextField.setAccessible(true);
Object node = table[i];
int chainLength = 0;
while (node != null) {
chainLength++;
// 获取键和值
java.lang.reflect.Field keyField = node.getClass().getDeclaredField("key");
keyField.setAccessible(true);
Object key = keyField.get(node);
java.lang.reflect.Field valueField = node.getClass().getDeclaredField("value");
valueField.setAccessible(true);
Object value = valueField.get(node);
System.out.println(" 链节点 " + chainLength + ": " + key + "=" + value);
node = nextField.get(node);
}
if (chainLength > 1) {
System.out.println(" 哈希冲突! 链长度: " + chainLength);
}
}
}
}
} catch (Exception e) {
System.out.println("无法查看HashMap内部结构: " + e.getMessage());
}
}
}
自定义简化版HashMap实现
// 自定义简化版HashMap,理解底层实现
class MyHashMap<K, V> {
private static final int DEFAULT_CAPACITY = 16;
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
static class Node<K, V> {
final K key;
V value;
Node<K, V> next;
final int hash;
Node(int hash, K key, V value, Node<K, V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
}
private Node<K, V>[] table;
private int size;
private int threshold;
private final float loadFactor;
@SuppressWarnings("unchecked")
public MyHashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR;
this.table = (Node<K, V>[]) new Node[DEFAULT_CAPACITY];
this.threshold = (int) (DEFAULT_CAPACITY * DEFAULT_LOAD_FACTOR);
}
public V put(K key, V value) {
int hash = hash(key);
int index = (table.length - 1) & hash;
// 检查是否已存在该键
Node<K, V> node = table[index];
while (node != null) {
if (node.hash == hash &&
(node.key == key || (key != null && key.equals(node.key)))) {
V oldValue = node.value;
node.value = value;
return oldValue;
}
node = node.next;
}
// 添加新节点
addNode(hash, key, value, index);
return null;
}
private void addNode(int hash, K key, V value, int index) {
Node<K, V> newNode = new Node<>(hash, key, value, table[index]);
table[index] = newNode;
if (++size > threshold) {
resize();
}
}
public V get(K key) {
int hash = hash(key);
int index = (table.length - 1) & hash;
Node<K, V> node = table[index];
while (node != null) {
if (node.hash == hash &&
(node.key == key || (key != null && key.equals(node.key)))) {
return node.value;
}
node = node.next;
}
return null;
}
@SuppressWarnings("unchecked")
private void resize() {
System.out.println("HashMap扩容: " + table.length + " -> " + (table.length * 2));
int newCapacity = table.length * 2;
threshold = (int) (newCapacity * loadFactor);
Node<K, V>[] newTable = (Node<K, V>[]) new Node[newCapacity];
// 重新哈希所有节点
for (Node<K, V> head : table) {
while (head != null) {
Node<K, V> next = head.next;
int newIndex = (newCapacity - 1) & head.hash;
head.next = newTable[newIndex];
newTable[newIndex] = head;
head = next;
}
}
table = newTable;
}
private int hash(K key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('{');
for (int i = 0; i < table.length; i++) {
Node<K, V> node = table[i];
while (node != null) {
sb.append(node.key).append('=').append(node.value).append(',');
node = node.next;
}
}
if (sb.length() > 1) {
sb.setLength(sb.length() - 1); // 移除最后一个逗号
}
sb.append('}');
return sb.toString();
}
}
public class CustomHashMapDemo {
public static void main(String[] args) {
MyHashMap<String, Integer> myMap = new MyHashMap<>();
myMap.put("Apple", 10);
myMap.put("Banana", 5);
myMap.put("Orange", 8);
myMap.put("Apple", 15); // 更新
System.out.println("自定义HashMap: " + myMap);
System.out.println("获取Apple: " + myMap.get("Apple"));
System.out.println("大小: " + myMap.size());
// 触发扩容
for (int i = 0; i < 20; i++) {
myMap.put("Key" + i, i);
}
System.out.println("扩容后: " + myMap);
System.out.println("大小: " + myMap.size());
}
}
4. Collections工具类
import java.util.*;
public class CollectionsPractice {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);
numbers.add(9);
System.out.println("原始列表: " + numbers);
// 排序
Collections.sort(numbers);
System.out.println("排序后: " + numbers);
// 逆序
Collections.reverse(numbers);
System.out.println("逆序后: " + numbers);
// 随机排序
Collections.shuffle(numbers);
System.out.println("随机排序后: " + numbers);
// 二分查找 (需要先排序)
Collections.sort(numbers);
int index = Collections.binarySearch(numbers, 5);
System.out.println("5的索引: " + index);
// 最大值和最小值
System.out.println("最大值: " + Collections.max(numbers));
System.out.println("最小值: " + Collections.min(numbers));
// 填充
Collections.fill(numbers, 0);
System.out.println("填充后: " + numbers);
// 创建线程安全的集合
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
// 不可修改的集合
List<String> unmodifiableList = Collections.unmodifiableList(Arrays.asList("A", "B", "C"));
Set<String> unmodifiableSet = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("A", "B", "C")));
Map<String, Integer> unmodifiableMap = Collections.unmodifiableMap(new HashMap<String, Integer>() {{
put("A", 1);
put("B", 2);
}});
// 尝试修改会抛出UnsupportedOperationException
try {
unmodifiableList.add("D");
} catch (UnsupportedOperationException e) {
System.out.println("不能修改不可修改集合: " + e.getMessage());
}
// 单元素集合
List<String> singletonList = Collections.singletonList("OnlyOne");
Set<String> singletonSet = Collections.singleton("OnlyOne");
Map<String, Integer> singletonMap = Collections.singletonMap("key", 1);
System.out.println("单元素列表: " + singletonList);
System.out.println("单元素集合: " + singletonSet);
System.out.println("单元素映射: " + singletonMap);
}
}
5. 综合练习与应用
import java.util.*;
public class CollectionExercises {
public static void main(String[] args) {
// 练习1: 统计单词频率
String text = "java is a programming language java is widely used java is popular";
Map<String, Integer> wordFrequency = countWordFrequency(text);
System.out.println("单词频率: " + wordFrequency);
// 练习2: 找出两个列表的共同元素
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
List<Integer> commonElements = findCommonElements(list1, list2);
System.out.println("共同元素: " + commonElements);
// 练习3: 实现LRU缓存
LRUCache<Integer, String> lruCache = new LRUCache<>(3);
lruCache.put(1, "A");
lruCache.put(2, "B");
lruCache.put(3, "C");
System.out.println("初始缓存: " + lruCache);
lruCache.get(1); // 访问1,使其成为最近使用的
lruCache.put(4, "D"); // 添加新元素,应该淘汰最久未使用的2
System.out.println("添加第四个元素后: " + lruCache);
// 练习4: 对学生按成绩排序
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 85));
students.add(new Student("Bob", 92));
students.add(new Student("Charlie", 78));
students.add(new Student("Diana", 92)); // 相同成绩
// 按成绩降序,成绩相同按姓名升序
students.sort((s1, s2) -> {
int scoreCompare = Integer.compare(s2.score, s1.score); // 降序
if (scoreCompare != 0) {
return scoreCompare;
}
return s1.name.compareTo(s2.name); // 升序
});
System.out.println("按成绩排序的学生:");
students.forEach(System.out::println);
}
// 统计文本中单词频率
public static Map<String, Integer> countWordFrequency(String text) {
Map<String, Integer> frequencyMap = new HashMap<>();
String[] words = text.split("\\s+");
for (String word : words) {
frequencyMap.put(word, frequencyMap.getOrDefault(word, 0) + 1);
}
return frequencyMap;
}
// 找出两个列表的共同元素
public static List<Integer> findCommonElements(List<Integer> list1, List<Integer> list2) {
Set<Integer> set1 = new HashSet<>(list1);
Set<Integer> commonSet = new HashSet<>();
for (Integer num : list2) {
if (set1.contains(num)) {
commonSet.add(num);
}
}
return new ArrayList<>(commonSet);
}
}
// 简单的LRU缓存实现
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
// 学生类
class Student {
String name;
int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return name + ":" + score;
}
}
6. 性能比较与最佳实践
import java.util.*;
public class PerformanceComparison {
public static void main(String[] args) {
final int SIZE = 100000;
// ArrayList vs LinkedList 性能比较
List<Integer> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();
// 添加元素性能
long startTime = System.nanoTime();
for (int i = 0; i < SIZE; i++) {
arrayList.add(i);
}
long arrayListAddTime = System.nanoTime() - startTime;
startTime = System.nanoTime();
for (int i = 0; i < SIZE; i++) {
linkedList.add(i);
}
long linkedListAddTime = System.nanoTime() - startTime;
System.out.println("添加" + SIZE + "个元素:");
System.out.println("ArrayList: " + arrayListAddTime / 1000000 + "ms");
System.out.println("LinkedList: " + linkedListAddTime / 1000000 + "ms");
// 随机访问性能
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
arrayList.get(SIZE / 2);
}
long arrayListAccessTime = System.nanoTime() - startTime;
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
linkedList.get(SIZE / 2);
}
long linkedListAccessTime = System.nanoTime() - startTime;
System.out.println("\n随机访问中间元素1000次:");
System.out.println("ArrayList: " + arrayListAccessTime / 1000 + "μs");
System.out.println("LinkedList: " + linkedListAccessTime / 1000 + "μs");
// HashMap vs TreeMap 性能比较
Map<Integer, String> hashMap = new HashMap<>();
Map<Integer, String> treeMap = new TreeMap<>();
// 添加性能
startTime = System.nanoTime();
for (int i = 0; i < SIZE; i++) {
hashMap.put(i, "Value" + i);
}
long hashMapPutTime = System.nanoTime() - startTime;
startTime = System.nanoTime();
for (int i = 0; i < SIZE; i++) {
treeMap.put(i, "Value" + i);
}
long treeMapPutTime = System.nanoTime() - startTime;
System.out.println("\n添加" + SIZE + "个元素到Map:");
System.out.println("HashMap: " + hashMapPutTime / 1000000 + "ms");
System.out.println("TreeMap: " + treeMapPutTime / 1000000 + "ms");
// 查找性能
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
hashMap.get(i);
}
long hashMapGetTime = System.nanoTime() - startTime;
startTime = System.nanoTime();
for (int i = 0; i < 1000; i++) {
treeMap.get(i);
}
long treeMapGetTime = System.nanoTime() - startTime;
System.out.println("\n查找1000个元素:");
System.out.println("HashMap: " + hashMapGetTime / 1000 + "μs");
System.out.println("TreeMap: " + treeMapGetTime / 1000 + "μs");
// 最佳实践总结
System.out.println("\n=== 集合选择最佳实践 ===");
System.out.println("1. 需要快速随机访问 → ArrayList");
System.out.println("2. 需要频繁在中间插入/删除 → LinkedList");
System.out.println("3. 需要快速查找/去重 → HashSet/HashMap");
System.out.println("4. 需要有序遍历 → TreeSet/TreeMap 或 LinkedHashSet/LinkedHashMap");
System.out.println("5. 需要维护插入顺序 → LinkedHashSet/LinkedHashMap");
System.out.println("6. 多线程环境 → ConcurrentHashMap, Collections.synchronizedXXX, 或CopyOnWriteArrayList");
}
}
这些代码示例涵盖了Java集合框架的核心概念,从基本使用到高级特性,再到性能优化和最佳实践。通过学习和实践这些示例,你将能够:
- 理解各种集合类的特性和适用场景
- 掌握集合的常见操作和遍历方式
- 了解集合的底层实现原理
- 学会如何选择合适的集合类解决实际问题
- 理解集合的性能特性和优化方法
建议你不仅运行这些代码,还要尝试修改它们,创建自己的变体,并解决实际问题来加深理解。集合框架是Java编程的核心组成部分,熟练掌握它们对你的编程能力提升至关重要。
3万+

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



