一、List、Set和Map的比较
集合类型 | 特点 | 实例 |
List | 有序集合,允许重复元素 | ArrayList, LinkedList, Vector |
Set | 无序集合,不允许重复元素 | HashSet, TreeSet, LinkedHashSet |
Map | 存储键值对,键唯一,值可以重复 | HashMap, Hashtable, TreeMap, LinkedHashMap |
- 有序性:
- List是有序的,可以通过索引来访问元素。
- Set和Map是无序的(但LinkedHashSet和LinkedHashMap保持了插入顺序)。
- 元素重复性:
- List和Map的值部分允许重复元素。
- Set不允许重复元素,但可以通过实现
equals()
和hashCode()
方法来定义“重复”的标准。
- 实现类的比较:
- ArrayList与LinkedList:ArrayList基于动态数组实现,支持快速随机访问,但在中间位置添加或删除元素时效率较低;LinkedList基于双向链表实现,支持在列表两端快速添加和删除元素,但随机访问效率较低。
- HashSet与TreeSet:HashSet基于哈希表实现,不保证元素的顺序;TreeSet基于红黑树实现,对元素进行自然排序或根据提供的
Comparator
进行排序。 - HashMap与Hashtable:HashMap是非同步的,支持null键和null值(但键只能有一个null);Hashtable是同步的,不支持null键和null值。
二、集合内部实现类的比较
List实现类比较
实现类 | 底层数据结构 | 线程安全性 | 访问效率 | 插入/删除效率 |
---|
ArrayList | 动态数组 | 非线程安全 | 高(随机访问) | 低(中间位置) |
LinkedList | 双向链表 | 非线程安全 | 低(需要遍历) | 高(两端操作) |
Vector | 动态数组 | 线程安全 | 高(随机访问) | 低(中间位置) |
Stack(继承Vector) | 动态数组 | 线程安全 | 高(随机访问) | 低 |
Set实现类比较
实现类 | 底层数据结构 | 线程安全性 | 元素排序 |
---|
HashSet | 哈希表 | 非线程安全 | 无序 |
TreeSet | 红黑树 | 非线程安全 | 自然排序或自定义排序 |
LinkedHashSet | 哈希表+双向链表 | 非线程安全 | 插入顺序 |
Map实现类比较
实现类 | 底层数据结构 | 线程安全性 | 键和值的null支持 | 排序 |
---|
HashMap | 哈希表+链表/红黑树 | 非线程安全 | 允许一个null键和多个null值 | 无序 |
Hashtable | 哈希表+链表 | 线程安全 | 不允许null键和null值 | 无序 |
TreeMap | 红黑树 | 非线程安全 | 不允许null键,允许null值 | 自然排序或自定义排序 |
LinkedHashMap | 哈希表+双向链表 | 非线程安全 | 允许一个null键和多个null值 | 插入顺序或访问顺序 |
三、集合比较方法
在Java中,对集合进行比较时,可以使用以下几种方法:
- 遍历比较:通过迭代集合中的元素,逐一比较每个元素的值。
- 使用
equals
方法:对于List和Set等集合类,可以直接使用equals
方法进行比较。但需要注意的是,equals
方法的实现依赖于元素的equals
方法和hashCode
方法。 - 使用
containsAll
方法:判断一个集合是否包含另一个集合的所有元素。 - 使用
retainAll
方法:返回两个集合的交集,即同时存在于两个集合中的元素。 - 使用
compareTo
方法(对于实现了Comparable
接口的集合元素):比较元素的大小。
四、Collection和Collections
| Collection | collections |
定义 | Collection 是Java集合框架中的一个接口,是集合类的根接口,它定义了集合的基本操作和行为,如添加、删除、遍历等。它是List、Set和Queue等子接口的父接口。 | Collections 是Java集合框架中的一个工具类,位于java.util 包中。它提供了一系列静态方法,用于对集合进行操作,如排序、查找、同步等。 |
性质 | 它是一个接口,不能直接实例化,需要通过其实现类(如ArrayList、LinkedList、HashSet等)来创建集合对象。 | 它是一个工具类,包含静态方法,不能直接实例化。它提供的方法用于操作实现了Collection 接口的集合对象。 |
功能 | 定义了集合的基本操作和行为,如添加(add )、删除(remove )、遍历(通过迭代器Iterator )等。它是所有集合类的父接口,提供了统一的操作规范。 | 提供了一系列静态方法,用于对集合进行高级操作,如排序(sort )、查找(如max 、min )、同步(synchronizedList 、synchronizedSet 等)、不可修改视图(unmodifiableList 、unmodifiableSet 等)。 |
使用场景 | 当需要创建一个集合对象,并对其进行基本操作(如添加、删除、遍历)时,应该使用Collection 接口的实现类(如ArrayList、LinkedList等)。 | 当需要对集合进行排序、查找、同步等高级操作时,应该使用Collections 类提供的静态方法。 |
五、Comparable和Comparator
| Comparable | Comparator |
定义 | 是Java中的一个接口,位于java.lang.Comparable 包中。 | 也是Java中的一个接口,位于java.util.Comparator 包中。 |
性质 | 它要求实现该接口的类具有自身比较的能力,即类的实例之间可以进行比较。 | 它是一个外部比较器,允许用户定义两个类实例之间的比较逻辑,而不需要修改类的源代码。 |
使用场景 | 当一个类的实例之间需要按照某种自然顺序进行排序时,该类应该实现Comparable接口,并重写compareTo方法。例如,String类就实现了Comparable接口,因此可以直接使用Collections.sort或Arrays.sort对字符串数组或集合进行排序。 | 当需要按照自定义的顺序对某个类的实例进行排序,而该类没有实现Comparable接口,或者虽然实现了但提供的排序方式不符合需求时,可以创建一个实现了Comparator接口的类来定义排序逻辑。然后,将这个Comparator对象作为参数传递给排序方法(如Collections.sort或TreeSet的构造函数)。 |
Comparable和Comparator区别:
-
定义和实现方式:
- Comparable是内比较器,要求实现该接口的类具有自身比较的能力,即类的实例之间可以直接进行比较。这通过实现compareTo方法来实现。
- Comparator是外比较器,它是一个独立的类,用于定义两个类实例之间的比较逻辑。这通过实现compare方法来实现。
-
排序的灵活性:
- 使用Comparable接口进行排序时,排序逻辑是固定的,与类的实例紧密绑定。如果需要改变排序逻辑,必须修改类的源代码。
- 使用Comparator接口进行排序时,排序逻辑是灵活的,可以根据需要定义不同的Comparator类来实现不同的排序逻辑。这样,可以在不修改类源代码的情况下改变排序方式。
-
同时使用时的优先级:
- 如果一个类同时实现了Comparable接口和提供了Comparator对象进行排序,那么Comparator对象的排序逻辑将优先于Comparable接口的排序逻辑。