我学的第一门编程语言时C语言,在C语言中是没有集合类型的,比较复杂的数据会用数组来保存,以至于我觉得数组是一种理所当然的必然存在。现在想一想,为什么需要用数组呢?我想答案是,当我们对有着同一数据类型的多个数据需要进行同一管理时,就可以靠数组来快捷实现。
数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的三个基本特点:
1.长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
2.其元素必须是相同类型,不允许出现混合类型。
3.数组类型可以是任何数据类型,包括基本类型和引用类型。
数组的声明实例:
double[] myList; // 首选的方法
或
double myList[]; // 效果相同,但不是首选方法,该风格是来自 C/C++ 语言
可以直接在定义数组的同时就为数组元素分配空间并赋值:
int[] myList = new int[] { 1,2,3,4,5 }; // 数组大小在初始化时固定,比如该数组只能存3个数
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组
数组定义与为数组元素分配空间并赋值的操作分开进行:
int[] myList = new int[5]; //预先定义指定的空间大小,此时数组中的每个值为null
myList[0] = 1;
myList[1] = 2;
myList[2] = 3;
myList[3] = 4;
myList[4] = 5;
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化:
int a2[] = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null
数组元素下标的合法区间:[0, length-1],如果超出区间,则会在程序运行时出现越界异常。我们可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。
当我们使用数组时,可以使用for循环来读取元素的值或者修改元素的,使用foreach循环只能进行读取(关于foreach循环可以阅读:《Java基础语法-foreach》),如下:
public class Test {
public static void main(String[] args){
int[] myList = new int[4];
// for循环,为数组元素赋值
for (int i = 0; i < myList.length; i++) {
myList[i] = i;
}
// for循环,打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.print(myList[i]);
}
System.out.println();
// foreach循环,打印所有数组元素
for (int i : myList) {
System.out.print(i);
}
}
}
---------------------------------------------------------------
输出结果为:
0123
0123
System类里也包含了一个static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,该方法可以实现数组的拷贝,具体参数含义简单来说就是:System.arraycopy(源数组,源数组的起始位置,目标数组,目标数组的起始位置,要复制的元素数量)。
来个实例感受一下:
public class Test {
public static void main(String[] args) {
String[] myList1 = { "a", "b", "c", "d" };
String[] myList2 = new String[10];
System.arraycopy(myList1, // 源数组
1, // 源数组的起始位置,注意数组的下标从0开始哦
myList2, // 目标数组
5, // 目标数组的起始位置,注意数组的下标从0开始哦
2); // 要复制的元素数量
for (String string : myList2) {
System.out.print(string+"\t");
}
}
}
-----------------------------------------------------
输出结果为:
null null null null null b c null null null
JDK提供的java.util.Arrays类,包含了常用的数组操作,是我们日常开发中的一个常用类。Arrays类包含了:排序、查找、填充、打印内容等常见的操作。常用方法:
方法 | 说明 |
---|---|
String toString(int[] a) | 打印数组元素的值 ,传入参数为待打印数组 |
void sort(int[] a) | 数组元素的排序 ,引用类型需实现Comparable |
int binarySearch(long[] a, long key) | 二分法查找指定元素,返回查找元素的下标 |
void fill(long[] a, long val) | 对数组进行填充 |
当然,这些方法里的变量类型可以是所有数据类型,Arrays中有很多重载。
注意这里的toString方法,与Object的toString是不同的,并不是重写了Object的toString,而是带有参数的重载。
来个Arrays类的实例:
public class Test {
public static void main(String[] args) {
String[] myList = { "b", "c", "d", "a" };
System.out.println(myList); //直接打印数组
System.out.println(Arrays.toString(myList)); // 打印数组元素的值
Arrays.sort(myList);//使用sort方法进行排序
System.out.println(Arrays.toString(myList)); // 打印数组元素的值;
System.out.println("该元素的索引:"+Arrays.binarySearch(myList, "c"));//二分法查找指定元素
Arrays.fill(myList, 1, 3, "e"); //将[1,3)索引的元素替换为"e";
System.out.println(Arrays.toString(myList));
}
}
--------------------------------------------------------------------
输出结果为:
[Ljava.lang.String;@7852e922
[b, c, d, a]
[a, b, c, d]
该元素的索引:2
[a, e, e, d]
二维及多维数组,就是数组当中的每一个元素,又是一个数组。(俄罗斯套娃…)但是实际开发中用的非常少。最多到二维数组(一般使用容器,二维数组用的都很少)。
声明与一维数组类似;初始化时,先初始化第一层,再第二层,以此类推;遍历时就使用嵌套循环,一层一层取出来。这里可能会觉得有点绕,那就多敲代码玩一玩,试一试,实践出真知,来个实例:
String[][] s = null; // 声明
s = new String[2][]; //初始化该数组,预先定义指定的空间大小:数组中存了2个数组元素。
//new String[2][],中的第二个[]中并不不能约束第二维的元素个数
s[0] = new String[2]; //初始化数组中的第0号元素,该元素也为数组
s[1] = new String[3]; //初始化数组中的第1号元素,该元素也为数组
s[0][0] = new String("Good"); //为二维数组的第0号元素的0号元素赋值
s[0][1] = new String("Luck"); //...一个个来
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
for (String[] strings : s) {
for (String strings2 : strings) { //嵌套foreach来遍历
System.out.println(strings2);
}
}
-------------------------------------------
输出结果为:
Good
Luck
to
you
!
关于嵌套循环遍历可能还好理解一些,关于声明,我这里用个人理解再阐述一下:
如果我们想声明一个一维数组,那么:
那当我们想声明一个二维数组,参照上面的步骤:
以上,是我的个人理解,若理解存在错误欢迎指正。