在之前的章节中我们学习过数组,可是我们知道,数组一旦确定了它的长度就永远不能改变
了。然而现实中很多情况下,我们并不知道要存放多少个数据,而是来一个存一个,那这个时候数
组就显得力不从心了。那么集合框架就闪亮登场了~
一、集合框架的性质:
那么我们首先来对比着数组来学习一下集合框架:
| 特性 | 数组 | 集合框架 |
|---|---|---|
| 长度 | 固定,一旦创建无法改变 | 动态,可根据需要自动扩容 |
| 元素类型 | 可以存储基本类型和对象 | 只能存储对象(但可通过包装类存储基本类型) |
| 功能 | 功能简单,主要就是通过索引存取 | 功能丰富,提供增删改查、排序、遍历、同步等各种方法 |
| 安全性 | 需要程序员自己维护,容易下标越界 | 有完善的迭代和异常机制,更安全(结合泛型) |
| 性能 | 结构简单,对于固定大小的数据,效率最高 | 不同实现类有不同的性能特点,可根据场景选择最优解 |
结论:对于固定大小、类型单一且对性能有极致要求的场景,数组仍是好选择。但对于绝大多数动态增长、需要复杂操作的业务数据,集合框架是更优、更现代的选择。
因此学习集合框架是十分必要滴~
二、集合框架体系:
在JAVA中,集合框架的以Collection和Map为两大核心接口(分别对应单列集合和多列集合),共同构成体系基础,用于储存和操作多个对象。
1、Collection接口:
是一个独立的根接口。属于单列集合
基础:属于 java.util 包,需要导包。是一个接口(interface)。
子接口:list、set
继承链:Collection<E> extends Iterable<E>。
特点:
存储单个元素对象(E)。
常用方法:
1. int size();
作用:返回此集合中的元素数量(元素个数)。
注意:如果集合包含的元素数大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE(但这种情况极其罕见)
2.boolean isEmpty();
作用:判断集合是否为空(即不包含任何元素)。
等价于 size() == 0,但通常isEmpty()的实现更高效
3.boolean contains(Object var1);
作用:判断此集合是否包含指定的元素。
底层机制:equals()方法。它会遍历集合中的元素,调用 o.equals(var1) 进行比较。这意味着要正确使用此方法,集合中存储的对象的类必须正确重写了 equals() 方法(例如String、Integer等包装类都已重写)。
4.Object[] toArray();
作用:将集合转换为一个 Object[] 数组。
注意:返回的是一个新数组,对数组的修改不会影响原集合,反之亦然。
缺点:返回的是 Object[] 类型,如果需要更具体的类型,需要进行强制类型转换,但可能引发 ClassCastException。
5.boolean add(E var1);
作用:向集合中添加一个元素。
注意:参数是一个对象(E 是泛型类型)。不会自动去重。对于 Set 接口的实现类,添加重复元素会返回 false;但对于 List 接口的实现类,允许重复,总是返回 true。
6.boolean remove(Object var1);
作用:从此集合中移除指定元素的单个实例(如果存在)。
底层机制:equals()方法。它会遍历集合,找到第一个满足 o.equals(var1) 为 true 的元素并将其移除。
注意:只移除第一个匹配到的元素(对于List而言顺序重要,对于Set则无所谓第一个)。
7. boolean containsAll(Collection<?> var1);
作用:判断此集合是否包含指定集合中的所有元素(即判断指定集合是否是此集合的子集)。
底层机制:对参数集合 var1 中的每个元素调用本集合的 contains(Object o) 方法。如果所有元素都包含,则返回 true。
8. boolean addAll(Collection<? extends E> var1);
作用:将指定集合中的所有元素添加到此集合中(并集操作)。
注意:参数中的泛型是 <? extends E>,意味着可以添加 E 或其子类类型的集合。
9. boolean removeAll(Collection<?> var1);
作用:移除此集合中所有也包含在指定集合中的元素(差集操作)。
底层机制:遍历指定集合 var1,对此集合调用 remove(Object o) 方法移除所有匹配的元素。
10、void clear();
作用:清空集合,移除所有元素。此方法执行后,集合将变为空集合。
11、boolean equals(Object var1);
作用:比较此集合与指定对象是否相等。
注意:此方法来自 Object 类,Collection 接口重新声明了它,但通常不强制要求实现类重写。List 和 Set 接口对此方法有更明确的约定。
List 要求:两个List相等当且仅当它们的大小相同,且对应位置的元素也相等(equals)。
Set 要求:两个Set相等当且仅当它们包含相同的元素(与顺序无关)。
一般原则:比较集合是否相等,通常应该使用 containsAll 等方法而不是直接依赖 equals,除非你清楚知道具体集合类的 equals 实现。
12. int hashCode();
作用:返回此集合的哈希码值。
约定:如果根据 equals(Object) 方法两个集合是相等的,那么调用它们各自的 hashCode 方法必须返回相同的整数结果。
为不相等的对象生成不同的整数结果可以提高哈希表(如HashMap)的性能。
注意:和 equals 方法一样,List 和 Set 接口对其实现类如何计算哈希码有各自的规则,通常基于其所有元素的哈希码进行计算。
2、List接口:
继承了 Collection 接口,属于单列集合。
基础:属于 java.util 包,需要导包。是一个接口(interface)。
继承链:List<E> extends Collection<E> extends Iterable<E>。
特点:
有序集合(Ordered):元素存入和取出的顺序一致。
带索引集合:可以通过下标(索引,从0开始)精确查找到对应的元素。
可存放重复元素:可以把相同的元素多次保存。
常用方法:
1.add(int index, E e):在指定索引位置插入元素。
2.addAll(int index, Collection<? extends E> c):将指定集合的所有元素插入到指定位置。
3.remove(int index):移除指定索引位置的元素。
4.remove(Object o):移除首次出现的指定元素。
5.E get(int index):获取指定索引位置的元素。(特殊用法:配合for循环遍历集合)
6.E set(int index, E element):用指定元素替换指定索引位置的元素。
7.boolean retainAll(Collection<?> c):取交集。仅保留此集合中也包含在指定集合中的元素。
3、Set接口:
继承了 Collection 接口,属于单列集合。
基础:属于 java.util 包,需要导包。是一个接口(interface)。
继承链:Set<E> extends Collection<E> extends Iterable<E>。
特点:
无序集合(Unordered):大多数Set实现(如HashSet)不保证元素的顺序(即存入和取出的顺序可能不一致)。LinkedHashSet和TreeSet除外。
不允许存放重复的元素:add(E e)方法会返回false。重复性的判断依赖于equals()和hashCode()方法。
没有索引:不能通过下标来访问元素。
常用方法:
完全继承自Collection接口,没有定义任何新方法。但由于其特性,像add(int index, E e), get(int index)这类依赖索引的方法是无法使用的。
2、Map接口:
是一个独立的根接口,不属于Collection。属于双列集合。
基础:属于 java.util 包,需要导包。是一个接口(interface)。
特点:
存储键值对(Key-Value) 映射。
Key不允许重复,每个Key最多映射一个Value。Value可以重复。
常用方法:
1. int size();
作用:返回此映射中键值对(key-value mappings)的数量。
2. V put(K key, V value);
作用:将指定的值(value)与此映射中的指定键(key)关联。
参数:K key (键), V value (值)
返回值:
如果此 key 之前已经存在,则用新 value 覆盖旧 value,并返回被覆盖的旧value。
如果此 key 之前不存在(是新的key),则添加该键值对,并返回 null。
3. void putAll(Map<? extends K, ? extends V> m);
作用:将指定映射 m 中的所有映射关系复制到当前映射中。相当于批量 put。
4. boolean containsKey(Object key);
作用:判断此映射是否包含指定键的映射关系。
底层机制:基于键的 hashCode() 和 equals() 方法进行判断。
5. boolean containsValue(Object value);
作用:判断此映射是否将一个或多个键映射到指定值。
底层机制:遍历所有值,并使用值的 equals() 方法进行判断。性能较低,因为可能需要遍历整个映射。
6. Set<K> keySet();
作用:返回此映射中包含的所有键的 Set 视图。
特点:返回的是一个“视图”,它由原映射支持。对视图的修改(如remove)会直接影响原映射。
返回的是 Set,因为 Map 的键是唯一的。
主要用途:遍历 Map 的所有键。
7. Collection<V> values();
作用:返回此映射中包含的所有值的 Collection 视图。
特点:同样是一个由原映射支持的视图。返回的是 Collection,因为 Map 的值是可以重复的。
主要用途:遍历或操作所有的值(如果你不关心对应的键)。
8. Set<Map.Entry<K, V>> entrySet();
作用:返回此映射中包含的所有键值对映射关系的一个 Set 视图。
特点:同样是一个由原映射支持的视图。是一个set。返回的是一个 Set<Map.Entry<K, V>> 类型的集合。
主要用途:高效遍历并同时访问或操作键和值(最主要、最常用的用途)
以上就是Map接口和Collection接口下的List接口、Set接口的介绍,下一节我们介绍Map、List、Set接口的实现类以及这些实现类的特点和它们之间的区别~
1007

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



