Java API 之集合框架进阶
前言: 本文主要讲解集合框架中的List、Set、Map接口中的进阶知识,主要是分析其底层原理和优缺点。
1. List 接口
1.1 ArrayList
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
// 创建一个ArrayList对象,初始容量为10
List<String> list = new ArrayList<>(10);
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 打印列表内容
System.out.println(list); // 输出: [Apple, Banana, Orange]
// 访问元素
System.out.println(list.get(1)); // 输出: Banana
// 插入元素
list.add(1, "Grape"); // 在索引1处插入元素
System.out.println(list); // 输出: [Apple, Grape, Banana, Orange]
// 删除元素
list.remove(2); // 删除索引2处的元素
System.out.println(list); // 输出: [Apple, Grape, Orange]
}
}
底层原理分析:
-
动态数组: ArrayList 底层使用一个数组来存储元素。
-
扩容机制: 当数组空间不足时,会创建一个新的更大容量的数组,将原数组元素复制到新数组中。扩容因子通常为 1.5,这意味着每次扩容,新数组的容量是原数组容量的 1.5 倍。例如,如果初始容量为 10,当添加第 11 个元素时,会创建一个容量为 15 的新数组,并将原数组元素复制到新数组中。
-
优点: 随机访问效率高,可以通过索引直接访问元素。
-
缺点: 插入和删除元素效率较低,尤其是对于中间位置的元素。因为需要移动后面的元素才能插入或删除元素。
1.2 LinkedList
import java.util.LinkedList;
import java.util.List;
public class LinkedListExample {
public static void main(String[] args) {
// 创建一个LinkedList对象
List<String> list = new LinkedList<>();
// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Orange");
// 打印列表内容
System.out.println(list); // 输出: [Apple, Banana, Orange]
// 访问元素
System.out.println(list.get(1)); // 输出: Banana
// 插入元素
list.add(1, "Grape"); // 在索引1处插入元素
System.out.println(list); // 输出: [Apple, Grape, Banana, Orange]
// 删除元素
list.remove(2); // 删除索引2处的元素
System.out.println(list); // 输出: [Apple, Grape, Orange]
}
}
底层原理分析:
-
双向链表: LinkedList 底层使用双向链表来存储元素。每个节点包含元素和指向前驱节点和后继节点的指针。
-
优点: 插入和删除元素效率高,尤其是在头部或尾部。因为只需要修改指针即可,不需要移动元素。
-
缺点: 随机访问效率较低,需要从头部或尾部开始遍历。
2. Set 接口
2.1 HashSet
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
// 创建一个HashSet对象
Set<String> set = new HashSet<>();
// 添加元素
set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Apple"); // 重复元素不会被添加
// 打印集合内容
System.out.println(set); // 输出: [Banana, Apple, Orange] (顺序可能不同)
// 判断元素是否存在
System.out.println(set.contains("Banana")); // 输出: true
}
}
底层原理分析:
-
哈希表: HashSet 底层使用哈希表来存储元素。哈希表是一种使用哈希函数将元素映射到数组中的特定位置的数据结构。
-
哈希冲突: 当多个元素的哈希值相同,就会发生哈希冲突。HashSet 使用链表或红黑树来解决哈希冲突。
-
优点: 元素查找效率高。
-
缺点: 元素顺序不固定。
2.2 TreeSet
import java.util.TreeSet;
import java.util.Set;
public class TreeSetExample {
public static void main(String[] args) {
// 创建一个TreeSet对象
Set<String> set = new TreeSet<>();
// 添加元素
set.add("Apple");
set.add("Banana");
set.add("Orange");
// 打印集合内容
System.out.println(set); // 输出: [Apple, Banana, Orange] (有序)
// 判断元素是否存在
System.out.println(set.contains("Banana")); // 输出: true
}
}
底层原理分析:
-
红黑树: TreeSet 底层使用红黑树来存储元素。红黑树是一种自平衡二叉搜索树,可以保证元素有序,并提供高效的查找、插入和删除操作。
-
优点: 元素有序,查找效率高。
-
缺点: 插入和删除元素效率相对较低。
3. Map 接口
3.1HashMap
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个HashMap对象
Map<String, Integer> map = new HashMap<>();
// 添加元素
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Orange", 3);
// 获取元素
System.out.println(map.get("Banana")); // 输出: 2
// 判断元素是否存在
System.out.println(map.containsKey("Apple")); // 输出: true
}
}
底层原理分析:
-
哈希表: HashMap 底层使用哈希表来存储键值对。
-
哈希冲突: 当多个键的哈希值相同,就会发生哈希冲突。HashMap 使用链表或红黑树来解决哈希冲突。
-
优点: 查找效率高。
-
缺点: 元素顺序不固定。
3.2 TreeMap
import java.util.TreeMap;
import java.util.Map;
public class TreeMapExample {
public static void main(String[] args) {
// 创建一个TreeMap对象
Map<String, Integer> map = new TreeMap<>();
// 添加元素
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Orange", 3);
// 打印Map内容
System.out.println(map); // 输出: {Apple=1, Banana=2, Orange=3} (有序)
// 获取元素
System.out.println(map.get("Banana")); // 输出: 2
// 判断元素是否存在
System.out.println(map.containsKey("Apple")); // 输出: true
}
}
底层原理分析:
-
红黑树: TreeMap 底层使用红黑树来存储键值对。
-
优点: 元素有序,查找效率高。
-
缺点: 插入和删除元素效率相对较低。
结语:以上就是关于 List、Set、Map接口中的进阶知识详解,希望对各位看官有所帮助,感谢各位看官的观看,下期见,谢谢~