Java容器
Java中的容器(Collections)是指用于存储和操作一组数据的对象。Java提供了丰富的容器类,这些类在java.util
包中实现。容器主要分为两大类:Collection和Map。以下将详细介绍Java容器的分类、常用实现类及其特点。
一、Java容器分类
1. Collection接口
Collection是一个存储单一元素的集合,可以进一步分为以下三种:
- List:有序且允许重复的集合。
- Set:无序且不允许重复的集合。
- Queue:用于存储具有优先级关系的队列集合。
2. Map接口
Map是用于存储键值对的集合,其中键是唯一的,值可以重复。
二、Collection接口的实现类
1. List接口
List接口的实现类有:ArrayList
、LinkedList
、Vector
。
1.1 ArrayList
特点:
- 基于动态数组实现。
- 随机访问速度快,查询效率高(O(1))。
- 插入和删除时需要移动元素,效率较低(O(n))。
使用场景:适合查询多、修改少的场景。
示例:
1
2
3
4
5
6
7
8
9
10import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
System.out.println(list); // 输出:[Java, Python, C++]
}
}ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
1
2
3import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
objectName: 对象名。
ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
添加元素
1
2
3
4
5
6
7
8
9
10
11
12import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites);
}
}访问元素
1
2
3
4
5
6
7
8
9
10
11
12import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites.get(1)); // 访问第二个元素
}
}修改元素
1
2
3
4
5
6
7
8
9
10
11
12
13import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.set(2, "Wiki"); // 第一个参数为索引位置,第二个为要修改的值
System.out.println(sites);
}
}删除元素
1
2
3
4
5
6
7
8
9
10
11
12
13import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.remove(3); // 删除第四个元素
System.out.println(sites);
}
}计算大小
1
2
3
4
5
6
7
8
9
10
11
12import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites.size());
}
}迭代数组列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
for (int i = 0; i < sites.size(); i++) {
System.out.println(sites.get(i));
}
}
}
// 或
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
for (String i : sites) {
System.out.println(i);
}
}
}ArrayList 排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import java.util.ArrayList;
import java.util.Collections; // 引入 Collections 类
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Taobao");
sites.add("Wiki");
sites.add("Runoob");
sites.add("Weibo");
sites.add("Google");
Collections.sort(sites); // 字母排序
for (String i : sites) {
System.out.println(i);
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import java.util.ArrayList;
import java.util.Collections; // 引入 Collections 类
public class RunoobTest {
public static void main(String[] args) {
ArrayList<Integer> myNumbers = new ArrayList<Integer>();
myNumbers.add(33);
myNumbers.add(15);
myNumbers.add(20);
myNumbers.add(34);
myNumbers.add(8);
myNumbers.add(12);
Collections.sort(myNumbers); // 数字排序
for (int i : myNumbers) {
System.out.println(i);
}
}
}
1.2 LinkedList
- 特点:
- 基于双向链表实现。
- 插入和删除效率高(O(1))。
- 随机访问效率低(O(n))。
- 使用场景:适合频繁插入、删除操作的场景。
- 示例:
1
2
3
4
5
6
7
8
9
10import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("A");
list.add("B");
list.addFirst("C");
System.out.println(list); // 输出:[C, A, B]
}
}
1.3 Vector
- 特点:
- 线程安全(方法加了
synchronized
修饰)。 - 性能较
ArrayList
低。
- 线程安全(方法加了
- 不推荐使用:在大部分场景下,
ArrayList
性能更优。
2. Set接口
Set接口的实现类有:HashSet
、TreeSet
、LinkedHashSet
。
2.1 HashSet
特点:
- 基于
HashMap
实现。 - 元素无序且不允许重复。
- 插入、删除、查找的时间复杂度为O(1)。
- 基于
使用场景:需要高效的去重操作。
示例:
1
2
3
4
5
6
7
8
9
10import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(2); // 重复元素不会被添加
System.out.println(set); // 输出:[1, 2]
}
}使用:
HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:1
import java.util.HashSet; // 引入 HashSet 类
以下实例我们创建一个 HashSet 对象 sites,用于保存字符串元素:
1
HashSet<String> sites = new HashSet<String>();
添加元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 引入 HashSet 类
import java.util.HashSet;
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
System.out.println(sites);
}
}判断元素是否存在
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 引入 HashSet 类
import java.util.HashSet;
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
System.out.println(sites.contains("Taobao"));
}
}删除元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 引入 HashSet 类
import java.util.HashSet;
// remove方法
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
sites.remove("Taobao"); // 删除元素,删除成功返回 true,否则为 false
System.out.println(sites);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 引入 HashSet 类
import java.util.HashSet;
// 删除集合中所有元素可以使用 clear 方法
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
sites.clear();
System.out.println(sites);
}
}计算大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 引入 HashSet 类
import java.util.HashSet;
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
System.out.println(sites.size());
}
}迭代 HashSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 引入 HashSet 类
import java.util.HashSet;
public class RunoobTest {
public static void main(String[] args) {
HashSet<String> sites = new HashSet<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Zhihu");
sites.add("Runoob"); // 重复的元素不会被添加
for (String i : sites) {
System.out.println(i);
}
}
}
2.2 TreeSet
- 特点:
- 基于
TreeMap
实现,底层是红黑树。 - 元素有序(自然顺序或自定义排序)。
- 插入、删除、查找的时间复杂度为O(log n)。
- 基于
- 使用场景:需要排序的集合。
- 示例:
1
2
3
4
5
6
7
8
9
10import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>();
set.add("Banana");
set.add("Apple");
set.add("Cherry");
System.out.println(set); // 输出:[Apple, Banana, Cherry]
}
}
2.3 LinkedHashSet
- 特点:
- 保证插入顺序。
- 基于
HashSet
,通过链表维护顺序。
- 使用场景:既需要去重又需要保持顺序。
- 示例:
1
2
3
4
5
6
7
8
9
10import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("A");
set.add("B");
set.add("C");
System.out.println(set); // 输出:[A, B, C]
}
}
3. Queue接口
Queue接口的常见实现类有:PriorityQueue
、LinkedList
(实现了Deque接口)。
3.1 PriorityQueue
- 特点:
- 基于堆实现。
- 元素按优先级排序。
- 使用场景:需要实现优先级队列。
- 示例:
1
2
3
4
5
6
7
8
9
10import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.add(10);
queue.add(5);
queue.add(20);
System.out.println(queue.poll()); // 输出:5(最小值)
}
}
三、Map接口的实现类
1. HashMap
1. HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 2. HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。 3. HashMap 是无序的,即不会记录插入的顺序。 4. HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- **特点**:
- 基于哈希表实现,键值对无序。
- 插入、删除、查找的时间复杂度为O(1)。
- JDK 1.8开始,链表长度超过阈值时使用红黑树优化。
- **示例**:
```java
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<>();
map.put("Apple", 3);
map.put("Banana", 2);
System.out.println(map.get("Apple")); // 输出:3
}
}使用:
HashMap 类位于 java.util 包中,使用前需要引入它,语法格式如下:1
import java.util.HashMap; // 引入 HashMap 类
以下实例我们创建一个 HashMap 对象 Sites, 整型(Integer)的 key 和字符串(String)类型的 value:
1
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
添加元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites);
}
}访问元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites.get(3));
}
}删除元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
Sites.remove(4);
System.out.println(Sites);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 删除所有键值对使用 cleat 方法:
// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
Sites.clear();
System.out.println(Sites);
}
}计算大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
System.out.println(Sites.size());
}
}迭代 HashMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 引入 HashMap 类
import java.util.HashMap;
public class RunoobTest {
public static void main(String[] args) {
// 创建 HashMap 对象 Sites
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
// 添加键值对
Sites.put(1, "Google");
Sites.put(2, "Runoob");
Sites.put(3, "Taobao");
Sites.put(4, "Zhihu");
// 输出 key 和 value
for (Integer i : Sites.keySet()) {
System.out.println("key: " + i + " value: " + Sites.get(i));
}
// 返回所有 value 值
for(String value: Sites.values()) {
// 输出每一个value
System.out.print(value + ", ");
}
}
}
2. TreeMap
- 特点:
- 基于红黑树实现,键有序。
- 插入、删除、查找的时间复杂度为O(log n)。
- 示例:
1
2
3
4
5
6
7
8
9import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<>();
map.put("Orange", 5);
map.put("Apple", 10);
System.out.println(map); // 输出:{Apple=10, Orange=5}
}
}
3. LinkedHashMap
- 特点:
- 保证插入顺序。
- 基于
HashMap
实现,维护了一个双向链表。
- 示例:
1
2
3
4
5
6
7
8
9import java.util.LinkedHashMap;
public class Main {
public static void main(String[] args) {
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("One", 1);
map.put("Two", 2);
System.out.println(map); // 输出:{One=1, Two=2}
}
}
四、容器工具类
Java提供了Collections
工具类,常用于容器的操作,如排序、查找、同步化等。
常用方法:
Collections.sort()
:排序。Collections.shuffle()
:随机打乱顺序。Collections.synchronizedList()
:将容器同步化。
示例:
1 | import java.util.ArrayList; |
五、总结
Java容器为我们提供了高效的数据存储和操作能力,选择合适的容器对于提升程序性能非常重要。在实际开发中,根据场景需求选择对应的容器,例如:
- 需要有序、可重复数据时使用
ArrayList
。 - 需要无序、去重数据时使用
HashSet
。 - 需要键值对存储时使用
HashMap
或TreeMap
。
深入理解每种容器的特性与适用场景是写出高质量Java代码的关键!