自学java基础--泛型 一、集合框架整体结构Collection单列集合存单个元素 │ ┌─────────────────┼─────────────────┐ │ │ │ List Set Queue 有序可重复 无序不重复 队列先进先出 │ │ ┌────┼────┐ ┌────┼────┐ │ │ │ │ │ │ ArrayList LinkedList Vector HashSet LinkedHashSet TreeSet Map双列集合存键值对 │ ┌───────────┼───────────┐ │ │ │ HashMap LinkedHashMap TreeMap Hashtable Properties二、List有序、可重复1、 ArrayList常用特点基于数组实现查询快增删慢中间位置// 创建 ListString list new ArrayList(); // 添加 list.add(苹果); // 末尾添加 list.add(香蕉); list.add(1, 橙子); // 在索引1位置插入 // 获取 String first list.get(0); // 苹果 // 修改 list.set(1, 葡萄); // 把索引1的元素改成葡萄 // 删除 list.remove(0); // 删除索引0的元素 list.remove(香蕉); // 删除第一个香蕉 // 遍历 for (String s : list) { System.out.println(s); } // 其他常用方法 list.size(); // 元素个数 list.isEmpty(); // 是否为空 list.contains(苹果); // 是否包含 list.indexOf(苹果); // 第一次出现的索引 list.clear(); // 清空ArrayList扩容过程初始容量 10存了 10 个元素 [a, b, c, d, e, f, g, h, i, j] 添加第 11 个元素时 1. 创建新数组容量 10 5 15 2. 把旧数组元素复制到新数组 3. 添加新元素 结果[a, b, c, d, e, f, g, h, i, j, k, null, null, null, null]注意频繁增删的场景不要用 ArrayList因为中间插入/删除需要移动大量元素。2、LinkedList特点基于双向链表实现增删快、查询慢ListString list new LinkedList(); // 用法和 ArrayList 一样但多了一些链表特有的方法 LinkedListString linkedList new LinkedList(); linkedList.addFirst(头部); // 头部添加 linkedList.addLast(尾部); // 尾部添加 linkedList.getFirst(); // 获取头部 linkedList.getLast(); // 获取尾部 linkedList.removeFirst(); // 移除头部 linkedList.removeLast(); // 移除尾部链表结构内存中的真实情况 ┌─────────────┐ ┌─────────────┐ │ 节点1 │ │ 节点2 │ │ 地址: 0x100 │ │ 地址: 0x200 │ │ │ │ │ │ prev: null │ │ prev: ─────┼───► 0x100节点1的地址 │ item: A │ │ item: B │ │ next: ─────┼────► │ next: null │ │ 0x200 │ │ │ └─────────────┘ └─────────────┘ │ ▲ │ │ └──────────────────────┘ 节点1.next 0x200节点2的地址 节点2.prev 0x100节点1的地址插入元素原来 节点1 ↔ 节点2 步骤1 新节点.prev 节点1 步骤2 新节点.next 节点2 步骤3 节点1.next 新节点 步骤4 节点2.prev 新节点 结果 节点1 ↔ 新节点 ↔ 节点2只需要修改 4 个指针引用不需要移动其他元素所以增删快。三、Set无序、不重复1、HashSet常用特点基于HashMap实现不保证顺序SetString set new HashSet(); set.add(苹果); set.add(香蕉); set.add(苹果); // ❌ 重复不会添加返回 false System.out.println(set); // [香蕉, 苹果] 或 [苹果, 香蕉]无序 // 判断是否存在 set.contains(苹果); // true // 其他方法 set.size(); set.isEmpty(); set.remove(苹果); set.clear();去重原理添加元素时 1. 调用元素的 hashCode() 计算哈希值 2. 根据哈希值找到数组位置 3. 如果该位置为空 → 直接放入 4. 如果该位置有元素 → 调用 equals() 比较 - equals 返回 true → 重复不添加 - equals 返回 false → 不重复以链表/红黑树形式存放2、LinkedHashSet特点HashSet的子类保持插入顺序SetString set new LinkedHashSet(); set.add(c); set.add(a); set.add(b); System.out.println(set); // [c, a, b] 保持插入顺序3、TreeSet特点基于红黑树自动排序SetInteger set new TreeSet(); set.add(3); set.add(1); set.add(2); System.out.println(set); // [1, 2, 3] 自动升序 // 自定义排序规则 SetString set2 new TreeSet((a, b) - b.compareTo(a)); // 降序 set2.add(b); set2.add(a); set2.add(c); System.out.println(set2); // [c, b, a]四、Map键值对1、HashMap常用MapString, Integer map new HashMap(); // 添加/修改 map.put(张三, 20); // 添加 map.put(张三, 21); // key已存在覆盖value // 获取 Integer age map.get(张三); // 21 Integer age2 map.get(李四); // null不存在 // 安全获取Java 8 Integer age3 map.getOrDefault(李四, 0); // 不存在返回 0 // 判断 map.containsKey(张三); // true map.containsValue(20); // false被覆盖成21了 // 删除 map.remove(张三); // 遍历多种方式 // 方式1遍历键 for (String key : map.keySet()) { System.out.println(key map.get(key)); } // 方式2遍历键值对推荐 for (Map.EntryString, Integer entry : map.entrySet()) { System.out.println(entry.getKey() entry.getValue()); } // 方式3Java 8 Lambda map.forEach((k, v) - System.out.println(k v));2、LinkedHashMap特点保持插入顺序或访问顺序// 保持插入顺序 MapString, Integer map new LinkedHashMap(); map.put(a, 1); map.put(b, 2); map.put(c, 3); System.out.println(map); // {a1, b2, c3} // 保持访问顺序LRU 缓存用 MapString, Integer lruMap new LinkedHashMap(16, 0.75f, true); lruMap.put(a, 1); lruMap.put(b, 2); lruMap.put(c, 3); lruMap.get(a); // 访问 a System.out.println(lruMap); // {b2, c3, a1} a移到最后3、TreeMap特点基于红黑树按键排序MapString, Integer map new TreeMap(); map.put(c, 3); map.put(a, 1); map.put(b, 2); System.out.println(map); // {a1, b2, c3} 按键升序总结需要存什么 │ ├── 单个元素允许重复有索引 → List │ ├── 查询多随机访问 → ArrayList │ └── 频繁增删 → LinkedList │ ├── 单个元素不重复 → Set │ ├── 不关心顺序 → HashSet │ ├── 保持插入顺序 → LinkedHashSet │ └── 需要排序 → TreeSet │ ├── 键值对 → Map │ ├── 不关心顺序 → HashMap │ ├── 保持插入顺序 → LinkedHashMap │ └── 按键排序 → TreeMap │ └── 先进先出 → Queue/Deque └── LinkedList 或 ArrayDeque