当前位置: 首页 > news >正文

Java学习进阶--集合体系结构

        Java 集合框架 (java.util 包) 是 Java 中用于存储和操作数据集合的核心组件,其设计精良、功能强大且高度灵活。理解其体系结构是 Java 进阶的关键一步。

一.集合的核心思想

接口与实现分离

        集合框架的核心在于接口定义了行为规范,而具体实现类提供了不同的底层数据结构和算法。应用程序应该面向0接口编程,这样可以在不改变代码逻辑的情况下更换实现,提高灵活性和可维护性。

集合框架的总体结构

Java 集合框架主要分为两大分支:Collection 和 Map

  • Collection 接口:是单列集合的根接口,用于存储单个元素。它有三个主要的子接口:ListSet 和 Queue
  • Map 接口:是双列集合的根接口,用于存储键值对。

二.Collection接口 -- 单列集合

        Collection是单列集合的祖宗接口,它的功能是全部的单列集合都可以继承使用的,下图是Collection接口下的继承和实现关系。

List系列集合:添加的元素是有序,可重复,有索引

Set系列集合:添加的元素是无序,不重复,无索引

Collection中的方法:

1. 基本操作方法

方法描述返回值示例
boolean add(E e)添加元素成功返回 truelist.add("Java")
boolean remove(Object o)删除指定元素存在并删除返回 trueset.remove("Python")
int size()返回元素数量集合大小queue.size()
boolean isEmpty()检查是否为空空集合返回 trueif (coll.isEmpty())
void clear()清空集合list.clear()

2. 批量操作方法

方法描述示例
boolean addAll(Collection<? extends E> c)添加另一个集合的所有元素list1.addAll(list2)
boolean removeAll(Collection<?> c)删除指定集合中存在的所有元素set.removeAll(subset)
boolean retainAll(Collection<?> c)仅保留指定集合中的元素(求交集)list.retainAll(subList)
boolean containsAll(Collection<?> c)检查是否包含指定集合的所有元素if (set.containsAll(subset))

3. 查询方法

方法描述示例
boolean contains(Object o)检查是否包含指定元素if (list.contains("Java"))
Object[] toArray()将集合转为数组Object[] arr = coll.toArray()
<T> T[] toArray(T[] a)将集合转为指定类型数组String[] arr = list.toArray(new String[0])

4. 迭代方法

方法描述示例
Iterator<E> iterator()返回迭代器Iterator<String> it = coll.iterator()
default void forEach(Consumer<? super T> action)使用函数式接口遍历list.forEach(System.out::println)

5. Java 8 新增默认方法

方法描述示例
default boolean removeIf(Predicate<? super E> filter)删除满足条件的元素list.removeIf(s -> s.length() < 3)
default Spliterator<E> spliterator()返回可分割迭代器Spliterator<String> sp = coll.spliterator()
default Stream<E> stream()返回顺序流coll.stream().filter(...)
default Stream<E> parallelStream()返回并行流coll.parallelStream().
import java.util.*;public class CollectionDemo {public static void main(String[] args) {// 1. 创建集合 (使用ArrayList实现)Collection<String> languages = new ArrayList<>();// 2. 添加元素languages.add("Java");languages.add("Python");languages.add("JavaScript");languages.add("C++");System.out.println("初始集合: " + languages); // [Java, Python, JavaScript, C++]// 3. 检查元素是否存在System.out.println("包含Java? " + languages.contains("Java")); // true// 4. 删除元素languages.remove("C++");System.out.println("删除C++后: " + languages); // [Java, Python, JavaScript]// 5. 批量操作 - 添加另一个集合Collection<String> frontend = new HashSet<>();frontend.add("HTML");frontend.add("CSS");frontend.add("JavaScript");languages.addAll(frontend);System.out.println("添加前端技术后: " + languages); // [Java, Python, JavaScript, HTML, CSS]// 6. 批量操作 - 删除另一个集合中的元素languages.removeAll(frontend);System.out.println("移除前端技术后: " + languages); // [Java, Python]// 7. 批量操作 - 保留交集Collection<String> popular = List.of("Java", "Python", "Go");languages.retainAll(popular);System.out.println("保留流行语言后: " + languages); // [Java, Python]// 8. 转换为数组Object[] array = languages.toArray();System.out.println("数组内容: " + Arrays.toString(array)); // [Java, Python]// 9. 遍历集合 - 迭代器System.out.print("迭代器遍历: ");Iterator<String> it = languages.iterator();while (it.hasNext()) {System.out.print(it.next() + " ");}System.out.println(); // 迭代器遍历: Java Python // 10. 遍历集合 - forEach (Java 8+)System.out.print("forEach遍历: ");languages.forEach(lang -> System.out.print(lang + " "));System.out.println(); // forEach遍历: Java Python // 11. Java 8 新特性 - removeIflanguages.removeIf(lang -> lang.startsWith("P"));System.out.println("移除P开头的语言后: " + languages); // [Java]// 12. Java 8 新特性 - streamlong count = languages.stream().filter(lang -> lang.length() > 3).count();System.out.println("长度大于3的元素数量: " + count); // 1 (Java)// 13. 清空集合languages.clear();System.out.println("清空后集合: " + languages); // []System.out.println("集合是否为空? " + languages.isEmpty()); // true}
}

三.Map 接口 -- 双列集合

1. “双列集合”的含义

“双列”: 指的是 Map 存储的元素由两个部分组成:

  • 键 (Key): 用于唯一标识元素的部分,相当于第一列。
  • 值 (Value): 与键相关联的数据部分,相当于第二列。

“集合”: 指的是 Map 本身是一个容器,用于存储和管理这些键值对 (Key-Value Pair) 元素。

2. Map 接口的核心概念

键值对 (Key-Value Pair): 这是 Map 存储的基本单位。每个元素都是一个包含 Key 和 Value 的配对。

键 (Key) 的唯一性: Map 中 不允许有重复的键。每个键最多只能映射到一个值。这是 Map 最重要的特性之一。

值 (Value) 的可重复性: 不同的键可以映射到相同的值。值可以重复。

映射关系 (Mapping): Map 的核心功能就是建立 Key 到 Value 的映射关系。通过一个 Key,可以高效地查找到其对应的 Value。这就像一本字典(Dictionary)或电话簿,通过名字(Key)查找电话号码(Value)。

无序性 (通常): 大多数 Map 实现类(如 HashMap不保证键值对的存储顺序(插入顺序或自然顺序)。但也有保证顺序的实现(如 LinkedHashMap 保证插入顺序,TreeMap 保证按键排序)。

不允许 null (视实现而定):

  • HashMapLinkedHashMap 允许一个 null 键和多个 null 值。
  • TreeMap 不允许 null 键(因为要排序),值可以为 null
  • ConcurrentHashMap 不允许 null 键和 null 值。
  • Hashtable 不允许 null 键和 null 值。

3. 为什么需要 Map?解决了什么问题?

Map 解决了需要根据 唯一标识符 快速查找、添加、删除或更新 关联数据 的场景。例如:

  • 字典/电话簿: 根据单词查释义,根据姓名查电话。
  • 数据库记录缓存: 用主键 ID 作为 Key,缓存整个记录对象作为 Value
  • 配置信息: 配置项名称作为 Key,配置值作为 Value
  • 对象属性映射: 属性名作为 Key,属性值作为 Value
  • 计数/统计: 用物品名称作为 Key,物品数量作为 Value
  • 图结构: 表示节点之间的连接关系(邻接表)。
实现类描述键有序性允许 null 键/值底层实现
HashMap最常用。 基于哈希表实现,提供最快的查找速度(平均 O(1))。不保证 (通常无序)1个 null键, 多个 null数组 + 链表 / 红黑树 (JDK8+)
LinkedHashMap继承 HashMap额外维护一个双向链表,保证迭代顺序 == 插入顺序保证插入顺序1个 null键, 多个 null哈希表 + 双向链表
TreeMap基于 红黑树 (Red-Black Tree) 实现。保证键值对按键的自然顺序或定制顺序排序。保证键的排序顺序键不能 null, 值可以红黑树
Hashtable古老的线程安全实现 (JDK 1.0)。不推荐使用,优先选 ConcurrentHashMap不保证键和值都不能 null哈希表
ConcurrentHashMap现代高效的线程安全实现 (JDK 5+)。支持高并发读写。不保证键和值都不能 null分段锁 / CAS (JDK8+)
Properties继承 Hashtable。专门处理 属性配置文件 (key=value 格式如 .properties)。通常按文件加载顺序键和值都不能 null哈希表

4. Map 接口的常用方法

增 / 改:

  • V put(K key, V value): 添加键值对。如果键已存在,则替换旧值并返回旧值;如果键不存在,添加并返回 null
  • void putAll(Map<? extends K, ? extends V> m): 将另一个 Map 的所有键值对添加到当前 Map

删:

  • V remove(Object key): 根据键删除键值对,返回被删除的值。键不存在返回 null
  • void clear(): 清空所有键值对。

查:

  • V get(Object key): 根据键获取对应的值。键不存在返回 null
  • boolean containsKey(Object key): 判断是否包含指定的键。
  • boolean containsValue(Object value): 判断是否包含指定的值(效率通常低于 containsKey)。

视图获取:

  • Set<K> keySet(): 返回此 Map 中所有键组成的 Set 集合(因为键唯一)。
  • Collection<V> values(): 返回此 Map 中所有值组成的 Collection 集合(值可以重复)。
  • Set<Map.Entry<K, V>> entrySet(): 返回此 Map 中所有键值对 (Map.Entry 对象) 组成的 Set 集合。这是遍历 Map 最常用的方式。

其他:

  • int size(): 返回键值对的数量。
  • boolean isEmpty(): 判断 Map 是否为空。
  • default V getOrDefault(Object key, V defaultValue): (JDK8+) 获取指定键的值,如果键不存在则返回默认值。
  • default V putIfAbsent(K key, V value): (JDK8+) 如果指定键尚未与值关联(或关联为 null),则将其与给定值关联并返回 null,否则返回当前值。
  • default boolean remove(Object key, Object value): (JDK8+) 仅当指定键当前映射到指定值时删除该条目。
  • default V replace(K key, V value): (JDK8+) 仅当指定键当前映射到某个值时,才替换该条目的值。
  • default boolean replace(K key, V oldValue, V newValue): (JDK8+) 仅当指定键当前映射到指定值时,才替换该条目的值。
Map<String, Integer> phoneBook = new HashMap<>();
phoneBook.put("Alice", 123456);
phoneBook.put("Bob", 654321);
phoneBook.put("Charlie", 789012);// 方式1:使用 Map.Entry 遍历 (最推荐,效率高,一次获取key和value)
for (Map.Entry<String, Integer> entry : phoneBook.entrySet()) {String name = entry.getKey();int phoneNumber = entry.getValue();System.out.println(name + ": " + phoneNumber);
}// 方式2:遍历键 (KeySet),然后通过键找值 (效率稍低于entrySet,因为多了一次get操作)
for (String name : phoneBook.keySet()) {int phoneNumber = phoneBook.get(name);System.out.println(name + ": " + phoneNumber);
}// 方式3:仅遍历值 (Values) (如果只需要值)
for (int phoneNumber : phoneBook.values()) {System.out.println("Phone: " + phoneNumber);
}// 方式4:Java 8+ 使用 forEach + Lambda 表达式 (简洁)
phoneBook.forEach((name, phoneNumber) -> System.out.println(name + ": " + phoneNumber));
http://www.lryc.cn/news/613744.html

相关文章:

  • 0_外设学习_ESP8266+云流转(no 0基础)
  • Vue 项目安全设置方案:XSS/CSRF 防护指南
  • UE4/UE5 Android 超大(视频)文件打包/防拷贝方案
  • 【开源工具】网络交换机批量配置生成工具开发全解:从原理到实战(附完整Python源码)
  • 小孙学变频学习笔记(十三)电动机参数的自动测量 矢量控制的转速反馈
  • 如何永久删除三星手机中的照片?
  • OpenBMC中libgpio架构与驱动交互全解析:从硬件映射到应用控制
  • 数据库表字段命名建议和最佳实践
  • 二十八天(数据结构:图的补充)
  • Deepoc具身智能开发板赋能采摘机器人的技术突破与应用实践
  • Android Studio第一个kotlin项目“Hello Android”
  • 机械学习--SVM 算法
  • Kotlin反射
  • Android 安全编程:Kotlin 如何从语言层保障安全性
  • 机械学习--k-means
  • 移动端网页调试实战,网络请求延迟与超时问题全链路排查指南
  • Java枚举类从入门到精通
  • gmssl私钥文件格式
  • 软件销售跟进思路
  • 弱电+机房+设备+运维资料合集方案(Word+PPT)
  • ORACLE物化视图快速刷新失败原因查找
  • 分治-快排-215.数组中的第k个最大元素-力扣(LeetCode)
  • oracle-plsql理解和操作
  • 【MongoDB】查询条件运算符:$expr 和 $regex 详解,以及为什么$where和$expr难以使用索引
  • [Oracle] LEAST()函数
  • 经常问的14002
  • Kafka生产者事务机制原理
  • 前端单元测试最佳实践(一)
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第八天(Vue框架及其安装)(完结篇) 重点 ! ! !
  • 基于Web的交互式坐标系变换矩阵计算工具