首先思考一个问题,我们这么多人是如何整理在一起上课的?
分了班级?对不对。所以我们一大帮子人进行集中、整理、放置在一起,就形成了一个“班级”。那么当出现了很多的数据呢?
数据,也可以像我们每一个人一样,集中合并放置在一起,进行批量存储和操作。数组就是集合当中最原始最简单的一种。
在 java 中,数组的特点在于:
- 只能存放同一数据类型的数据
- 所有元素数据存放在连续内存空间
- 数组空间大小一旦确定,不可更改
这三个特点也是 java 中数组的缺点,但由于数组的不可被修改性,后面我们还会学习其他的数据结构。
声明方式
声明方式存在两种
- 明确数据情况
- 未知具体数据情况,仅知道元素个数
明确数据情况
这种声明方式适合于明确数组中数据的值。
语法:元素类型 [] 数组名称 = {数据1, 数据2, ... 数据n};```java // 表示内存中开辟了一块空间用于存储 5 个整数 int [] numbers = {1, 2, 3, 4, 5};
// 表示内存中开辟了一块空间用于存储 3 个浮点数,56 也会被存储为 56.0 double [] rainFall = {12.3, 78.4, 56};
// 表示内存中开辟了一块空间用于存储 4 个字符串 String[] users = {“zhangsan”, “lisi”, “wangwu”, “zhaoliu”};
对于数组(变量)名 numbers、rainFall、users 都是一个引用,指向了内存中的地址,以便我们对数组进行操作。<a name="YoeEg"></a>### 未知数据情况这种方式适用于不确定数组中值,只明确存放的个数。<br />语法:`数据类型 [] 数组名称 = new 数据类型[数组长度];````java// 声明了一个名为 numbers 长度为 8 的数组,用于未来存放整数int [] numbers = new int[8];// 声明了一个名为 rainFall 长度为 10 的数组,用于未来存放小数double[] rainFall = new double[10];
存放方式
当书写完数组的声明后,它在内存中的存放方式实际上是一个引用,通过变量名字 “numbers”、“rainFall”、“users” 指向了一块内存地址。
像之前我们书写的 int a = 5;,char c = 'c'; 5 和字符 c 都是属于基本数据类型,对吧?基本数据类型的变量空间中存放的是值本身,引用类型的变量空间中存放的是引用,该引用指向真正的数据。
总结下来就是:
- 基本数据类型的变量空间中存放的是值本身
- 引用类型的变量空间中存放的是引用,该引用指向真正的数据
默认初始化值
在对于第二种只明确个数的声明方式int[] numbers = new int[8]每个元素会默认初始化为 0。
- 若元素是基本数据类型,赋值初始化为 0
- int 类型,各元素初始化为 0
- double/float 类型,各元素初始化为 0.0
- char 类型,各元素初始化为 ASCII 码为 0 的字符(一个空字符)
- boolean 类型,各元素初始化为 false
- 若元素为引用数据类型,赋值初始值为 null
int [] numbers = new int[10]; // 访问 numbers[0] 得到 0double [] rainFall = new double[5]; // 访问 rainFall[0] 得到 0.0String[] names = new String[5];// 访问 names[0] 得到 null
操作数组中的元素
数组中的元素通过数组名[下标]进行操作。下标相当于元素在数组中的编号,下标从 0 开始,最大下标为数组长度减1。
若下标不在范围,会报异常:ArrayIndexOutOfBoundsException即(数组下标越界异常)。数组有一个length属性用来代表数组的长度,可以避免数据访问时越界。 ```java int numbers[] = {1, 2, 3, 4, 5}; System.out.println(numbers[886]); // ArrayIndexOutOfBoundsException: Index 886 out of bounds for length 5
System.out.println(numbers.length); // 5
<a name="ILXad"></a>## 遍历数组遍历数组就是指依次拿到数组中的每一个元素,进行相应的操作。我们已知数组下标从 0 开始,所以可以使用循环取得数组中每一项。```javafor(int i = 0; i < arr.length; i++){// 相应操作}
数组的拷贝
我们已经得知数组是属于引用类型的,数组变量名只是一个引用:
int arr1[] = {1, 2, 3};int arr2[] = arr1; // arr1 和 arr2 指向了同一块内存空间arr1[0] = 886; // 其中一个被改变System.out.println(arr2[0]); // 另一个也同时被改变
为了使两块内存空间独立开来,就需要对“数据”进行拷贝。尝试对 int arr[] = {1, 2, 3};进行拷贝。
排序
对集合中元素进行排序也是非常常用基本操作。排序的方式有很多,冒泡、选择、自然等等,语言自带了排序方法,对于手写排序,主要掌握冒泡或者选择排序。
/*选择排序数组中一个数和后面所有数字一一比较*/int arr[] = {3, 15, 6, 2, 8, 19};for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i] > arr[j]) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}
/*冒泡排序数组中的数字两两比较*/for (int count = 1; count < arr.length; count++) {for (int i = 0; i < arr.length - 1; i++) {if (arr[i] > arr[i + 1]) {int temp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = temp;}}}for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}
