1. Java集合框架概述
1.1 集合的基本概念
集合是用于存储多个对象的容器,定义了一系列对多个对象进行操作的方法。集合可以实现类似数组的功能,但更加灵活。
1.2 集合与数组的区别
- 数组的长度是固定的,而集合的长度可以动态变化。
- 数组可以存储基本数据类型和引用类型,而集合只能存储引用类型(如果需要存储基本数据类型,可以使用对应的包装类)。
1.3 集合框架的位置
Java集合框架提供了一套高效且易于使用的接口和类,它们位于java.util
包中。
2. Comparable与Comparator的区别
2.1 Comparable接口
Comparable
接口位于java.lang
包中,包含一个compareTo(Object obj)
方法,用于实现自然排序。
2.2 Comparator接口
Comparator
接口位于java.util
包中,包含一个compare(Object obj1, Object obj2)
方法,用于实现定制排序。
当需要对集合进行自定义排序时,可以通过实现Comparable
接口或使用Comparator
接口。如果需要实现多种排序方式,可以同时重写compareTo()
方法并使用多个Comparator
实例。
2.3 Comparable具体案例
以下是一个使用Comparable
接口进行排序的示例:
import java.util.TreeSet;
public class TestComparable {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet<>();
for (int i = 5; i >= 1; i--) {
treeSet.add(new Student(i));
}
System.out.println(treeSet.toString());
}
}
class Student implements Comparable {
int age;
public Student(int age) {
this.age = age;
}
// 按照age的大小正序排序
@Override
public int compareTo(Student student) {
return this.age - student.age;
}
@Override
public String toString() {
return "Student{" + "age=" + age + '}';
}
}
运行结果:
2.4 Comparator具体案例
以下是一个使用Comparator
接口进行排序的示例:
public static void main(String[] args) {
TreeSet treeSet = new TreeSet<>(new Comparator() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length() - o2.length();
int n2 = o1.compareTo(o2);
return n1 == 0 ? n2 : n1;
}
});
treeSet.add("Hello World!");
treeSet.add("Java the best!");
treeSet.add("C#");
treeSet.add("Go");
treeSet.add("Python");
treeSet.add("C");
treeSet.add("C++");
treeSet.add("JavaWeb");
treeSet.add("Javascript");
treeSet.add("CSS");
treeSet.add("HTML");
treeSet.add("Angular");
System.out.println(treeSet.toString());
}
运行结果:
3. 集合框架底层数据结构总结
3.1 List接口实现
- ArrayList: 基于动态数组实现,支持快速随机访问。
- Vector: 与ArrayList类似,但线程安全。
- LinkedList: 基于双向链表实现,支持高效的插入和删除操作。
3.2 Set接口实现
- HashSet (无序、唯一): 基于HashMap实现,底层使用哈希表存储元素。
- LinkedHashSet (有序、唯一): 继承自HashSet,内部使用LinkedHashMap实现,保持插入顺序。
- TreeSet (有序、唯一): 基于红黑树实现,支持按自然顺序或定制顺序排序。
3.3 Map接口实现
- HashMap: JDK 1.8之前使用数组+链表实现,JDK 1.8之后在链表长度超过8时转换为红黑树,以提高查找效率。
- LinkedHashMap: 继承自HashMap,内部使用双向链表维护插入顺序或访问顺序。
- Hashtable: 类似于HashMap,但线程安全,不支持null键和值。
- TreeMap: 基于红黑树实现,支持按自然顺序或定制顺序排序。
4. 如何选择合适的集合类
选择合适的集合类应考虑以下因素:
- 需要根据键值获取元素时,选择Map接口下的集合。
- 需要排序时,选择TreeMap。
- 不需要排序时,选择HashMap。
- 需要保证线程安全时,选择ConcurrentHashMap。
- 只需存放元素值时,选择实现Collection接口的集合。
- 需要保证元素唯一时,选择实现Set接口的集合,如TreeSet或HashSet。
- 不需要保证唯一性时,选择实现List接口的集合,如ArrayList或LinkedList。