目录
在Java编程中,数组和集合是两种重要的数据结构,它们用于存储和管理一组数据。虽然它们在某些方面有相似之处,但各自具有独特的特点和适用场景。本文将详细介绍Java中的数组(包括一维和二维数组)和集合,并通过代码示例展示它们的使用方法和注意事项。
一、一维数组
数组是一种固定大小的数据结构,用于存储相同类型的元素。在Java中,数组是对象,可以通过索引来访问数组中的元素。数组的大小在创建时确定,之后无法改变
1. 一维数组的声明和初始化
// 声明一个整型数组,大小为5
int[] numbers = new int[5];
// 初始化数组元素
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
// 也可以在声明时直接初始化
int[] anotherNumbers = {1, 2, 3, 4, 5};
2. 一维数组的遍历
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
3. 一维数组的注意事项
- 数组的大小是固定的,一旦创建就无法改变。
- 数组的元素类型必须相同。
- 访问数组时,如果索引超出范围,会抛出
ArrayIndexOutOfBoundsException
异常。
二、二维数组
二维数组是一种特殊的数组,其元素本身也是数组。二维数组通常用于表示矩阵或表格数据。
1. 二维数组的声明和初始化
// 声明一个3x3的整型二维数组
int[][] matrix = new int[3][3];
// 初始化二维数组元素
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[0][2] = 3;
matrix[1][0] = 4;
matrix[1][1] = 5;
matrix[1][2] = 6;
matrix[2][0] = 7;
matrix[2][1] = 8;
matrix[2][2] = 9;
// 也可以在声明时直接初始化
int[][] anotherMatrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
2. 二维数组的遍历
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
3. 二维数组的注意事项
- 二维数组的大小也是固定的,一旦创建就无法改变。
- 二维数组的元素类型必须相同,且每个子数组的长度也可以相同或不同(但在实际应用中,为了处理方便,通常每个子数组的长度是相同的)。
- 访问二维数组时,如果索引超出范围,同样会抛出
ArrayIndexOutOfBoundsException
异常。

4.简单的二维数组代码示例
题目:某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:22,66,44
第二季度:77,33,88
第三季度:25,45,65
第四季度:11,66,99
根据以上数据,创建二维数组,并打印输出以下内容:
1. 指出累计营业额最高的季度是哪个季度,同时输出该季度的营业额。
2. 打印输出全年的营业额之和,并计算全年的月营业额的平均值。
3. 统计低于平均营业额的月份,分别为哪几个月。
三、集合
集合是Java中用于存储和管理一组对象的框架。与数组相比,集合具有更大的灵活性和动态性。Java集合框架提供了多种集合类型,如List、Set、Map等。
1.集合接口
a.Collection接口
- 是集合框架中最基本的接口,代表一组不允许重复的对象。
- 提供了一些基本的方法,如
add(Object o)
、remove(Object o)
、contains(Object o)
、size()
等。
b.List接口
- 继承自Collection接口,是一个有序的集合,允许重复元素。
- 提供了按索引访问元素的方法,如
get(int index)
、set(int index, Object element)
等。 - 还提供了列表迭代器(ListIterator),可以双向遍历列表。
c.Set接口
- 继承自Collection接口,是一个不允许重复的集合。
- 集合中的元素没有特定的顺序。
- 常用的实现类有HashSet、LinkedHashSet、TreeSet等。
d.Map接口
- 不是Collection的子接口,代表键值对的集合,每个键只能映射到一个值。
- 提供了按键访问值的方法,如
get(Object key)
、put(Object key, Object value)
等。 - 常用的实现类有HashMap、LinkedHashMap、TreeMap等
2. List集合
List集合是一个有序的集合,允许重复元素。List集合中的元素可以通过索引来访问
import java.util.ArrayList;
import java.util.List;
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// 遍历List集合
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 使用增强for循环遍历List集合
for (String fruit : list) {
System.out.println(fruit);
}
3. Set集合
Set集合是一个无序的集合,不允许重复元素。Set集合中的元素没有索引,因此不能通过索引来访问
import java.util.HashSet;
import java.util.Set;
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
set.add("Apple"); // 重复元素不会被添加
// 遍历Set集合
for (String fruit : set) {
System.out.println(fruit);
}
4. Map集合
Map集合是一个键值对的集合,每个元素都有一个唯一的键和一个值。Map集合中的元素没有索引,但可以通过键来访问对应的值。
import java.util.HashMap;
import java.util.Map;
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
// 遍历Map集合
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
5.集合实现类
a. ArrayList
- 基于动态数组实现的List接口。
- 支持随机访问,查询效率高,但插入和删除操作需要移动元素,效率较低。
b. LinkedList
- 基于双向链表实现的List接口。
- 插入和删除操作效率高,因为只需要改变相邻节点的引用。
- 但不支持随机访问,查询效率较低。
c. HashSet
- 基于哈希表实现的Set接口。
- 不保证元素的顺序。
- 提供了快速的查找和更新操作。
d. LinkedHashSet
- 继承自HashSet,维护了一个链表来保证插入顺序。
- 提供了有序的遍历。
e. TreeSet
- 基于红黑树实现的Set接口。
- 可以保持元素的排序。
- 提供了自然排序或根据提供的比较器进行排序。
f. HashMap
- 基于哈希表实现的Map接口。
- 不保证映射的顺序。
- 提供了快速的查找和更新操作。
g. LinkedHashMap
- 继承自HashMap,维护了一个双向链表来保持插入顺序。
- 提供了有序的遍历。
h. TreeMap
- 基于红黑树实现的Map接口。
- 可以保持键的排序。
- 提供了自然排序或根据提供的比较器进行排序。
6. 集合的遍历
a. for-each循环
- 适用于List、Set和Map的entrySet()遍历。
- 简洁明了,但无法获取元素的索引或修改集合。
b. Iterator迭代器
- 适用于所有实现了Iterable接口的集合。
- 提供了hasNext()、next()等方法来遍历集合。
- 可以通过remove()方法删除当前元素(在调用next()方法之后)。
c. ListIterator
- 是Iterator的子接口,专门用于List集合。
- 提供了add(Object o)、set(Object o)、hasPrevious()、previous()等方法。
- 可以双向遍历List集合。
d. for循环与索引
- 适用于List集合。
- 可以通过索引来访问和修改集合中的元素。
e. Map的遍历
- 可以使用for-each循环遍历entrySet()、keySet()或values()。
- entrySet()遍历提供了键和值的组合。
- keySet()遍历只提供了键。
- values()遍历只提供了值。
7. 集合的注意事项
类型安全
- 使用泛型来指定集合中元素的类型,以避免类型转换错误。
空指针异常
- 在向集合中添加元素之前,确保元素不为null(对于不允许null元素的集合)。
线程安全
- 大多数集合实现都是非线程安全的。如果需要在多线程环境中使用集合,请考虑使用同步集合(如Collections.synchronizedList()、Collections.synchronizedMap()等)或并发集合(如ConcurrentHashMap、CopyOnWriteArrayList等)。
性能考虑
- 根据具体需求选择合适的集合实现。例如,如果需要频繁的随机访问,则ArrayList可能更适合;如果需要频繁的插入和删除操作,则LinkedList可能更适合。
四、总结
数组(包括一维和二维数组)和集合是Java编程中常用的数据结构,它们各自具有独特的特点和适用场景。数组适用于存储固定大小和相同类型的元素,而集合则提供了更大的灵活性和动态性,适用于存储和管理一组对象。在选择使用数组还是集合时,需要根据具体的需求和场景来做出决策。
希望本文能够帮助你更好地理解Java中的数组(包括一维和二维数组)和集合,并通过代码示例掌握它们的使用方法和注意事项。