【零碎小知识点 】(三)Java集合框架深入与实践

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集合框架的核心概念,从基本使用到高级特性,再到性能优化和最佳实践。通过学习和实践这些示例,你将能够:

  1. 理解各种集合类的特性和适用场景
  2. 掌握集合的常见操作和遍历方式
  3. 了解集合的底层实现原理
  4. 学会如何选择合适的集合类解决实际问题
  5. 理解集合的性能特性和优化方法

建议你不仅运行这些代码,还要尝试修改它们,创建自己的变体,并解决实际问题来加深理解。集合框架是Java编程的核心组成部分,熟练掌握它们对你的编程能力提升至关重要。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值