标签:eps elf sap acm ssg wap 建立 ade DDM
目录
什么是数组?顾名思义,就是用来存储一组数据
的一种数据结构。
数组可以存储多个数据,但是只能是相同类型
的数据。每个数组元素存放一个数据,我们可以通过数组的索引去访问相应的元素。数组的索引从0开始,则最后一个数组元素的索引是(数组长度-1)
。
因为Java是面向对象的语言,而类与类之间可以支持继承关系。故这样可能产生一个数组里可以存放”多种数据类型“的假象。
例如一个存放水果的数组,那么我们就只能往里面存放”水果“这个类型的数据——意思就是,我们不单单可以存”水果“,我们还能往数组里面存放”西瓜“、”苹果“、”柚子“等水果。
为什么呢?因为”西瓜“、”苹果“、”柚子“,它们都继承于父类”水果“,都是属于水果类型的。
Java语言中数组必须先初始化,然后才可以使用。所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初值。
那么能不能只分配内存空间,而不赋初始值呢?答案是不能。因为一旦为数组元素分配了内存空间,那么每个内存空间里存储的内容就是该数组元素的值。
初始值的获得方式有两种方式:
静态初始化:由程序员显示指定每个数组元素的初始值,由系统决定数组长度。静态初始化的语法格式如下:
int[] arr = new int[] { 1, 2, 3, 4, 5 };
动态初始化:程序员只指定数组长度,由系统为数组元素分配初始值。动态初始化的语法格式如下:
int[] arr = new int[5];
注意:不要在数组初始化时既指定数组长度,又为每个数组元素分配初始值。
public class TestArray {
public static void main(String[] args) {
// 创建一个double类型的数组
double[] myList = { 1.9, 2.9, 3.4, 3.5 };
// 传统for循环打印数组元素内容
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
}
// foreach循环打印数组元素内容
// 在 foreach迭代数组元素时候,并不能改变元素数组的值,因此不要对循环变量进行赋值
for (double d : myList) {
System.out.println(d);
}
// 计算所有元素的总和
double total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println("Total is " + total);
// 查找最大元素
double max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max)
max = myList[i];
}
System.out.println("Max is " + max);
}
}
数组是一种引用
数据类型,数组引用变量只是一个引用。这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可通过该数组变量来访问数组元素。
实际的数组对象其实是被存储在堆内存中。而引用该数组对象的数组引用变量通常存储在栈中。数组在内存中的存储示意图如下图所示。
那么,为什么数组要分两种形式来存放呢?
因为当一个方法执行时, 每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是存放在栈内存中的。
在程序中创建一个对象时,这个对象将会被保存到运行时数据区(堆)中,以便反复利用(因为创建对象的成本比较高)。堆内存中的对象不会随着方法的结束而销毁,当方法结束后,该对象还可能被另外一个引用变量所引用。
当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它(也可以将该数组变量赋为null,切断了呃数组引用变量和实际数组之间的引用关系)。
只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组。
但,这种操作可能会让人产生数组的长度可变的错觉,如下代码所示。
public class test {
public static void main(String[] args) {
// 定义并初始化数组,使用动态初始化
int[] a = new int[4];
// 定义并初始化数组,使用静态初始化
int[] b = { 5, 7, 20 };
// 输出a数组的长度4
System.out.println("b数组的长度为:" + a.length);
// 循环输出a数组的元素
for (int arr : a) {
System.out.println(arr);
}
// 循环输出b数组的元素
for (int arr2 : b) {
System.out.println(arr2);
}
// 因为a是int[]类型,b也是int[]类型,所以可以将b的值赋给a。
// 也就是让b引用指向a引用指向的数组
a = b;
// 再次输出a数组的长度3
System.out.println("a数组的长度为:" + a.length);
}
}
运行如上代码,我们可以看到,a数组最开始的长度为4,当b引用变量指向a数组时,长度变成了3。这会误让人以为a数组长度变成了3。我们必须始终牢记数组在内存中的存储方式:**定义并初始化一个数组时,内存中会分配两个空间,一个存放数组的引用变量(栈),而另一个存放数组的本身(堆)。上诉代码的内存图示见图2。
通过图示分析,我们可以得知,在a没有指向b数组时,a数组的长度为4。当执行代码b=a
后,实际上就变成了a、b引用变量同时指向b数组,故打印出来a指向数组的长度为3,也就是b数组的长度。而原来的a数组失去了引用,变成了垃圾,只有等待垃圾回收机制来回收它——并且在此之前它的长度不会改变,直到它彻底消失。
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组,例如:
String str[][] = new String[3][4];
直接为每一维分配空间,格式如下:
type arrayName = new type[arraylenght1][arraylenght2];
定义的类型可以为基本数据类型
或复合数据类型
。arraylenght1 和 arraylenght2 必须为正整数,arraylenght1 为行数
,arraylenght2 为列数
。
例如:
int a[][] = new int[2][3];
解析:二维数组 a 可以看成一个两行三列的数组。
从最高维开始,分别为每一维分配空间,例如:
String s[][] = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
解析:s[0]=new String[2] 和 s[1]=new String[3] 是为最高维分配引用空间,也就是为最高维限制其能保存数据的最长的长度,然后再为其每个数组元素单独分配空间 s0=new String("Good") 等操作。
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
具有以下功能:
fill
方法。sort
方法,按升序。equals
方法比较数组中元素值是否相等。binarySearch
方法能对排序好的数组进行二分查找法操作。示例代码如下:
import java.util.Arrays;
public class ArraysTest {
public static void main(String[] args) {
// 定义一个一维数组
int[] arr = { 22, 47, 1, 68, 35 };
// 使用sort()方法对数组arr[]进行升序排序
Arrays.sort(arr);
System.out.println("打印出sort()方法排序后的数组:");
for (int i : arr) {
System.out.println(i);
}
System.out.println("=========================");
// 使用二分法查询key值在数组中的索引,如果不存在则返回负数。
// 但是调用该方法前,必须要对数组进行升序排序,这样才能得到正确的结果
System.out.println("该key在数组的索引是:" + Arrays.binarySearch(arr, 47));
System.out.println("=========================");
int[] b = Arrays.copyOf(arr, 6);
// 使用Arrays.copyof()复制的数组,如果指定的长度比原数组短
// 则只复制指定长度数组;反之,多出来的长度则以0(int默认填充类型)填充
for (int i : b) {
System.out.println(i);
}
System.out.println("=========================");
// 因为b数组长度比arr数组长度长,而且元素也并不相同,所以下面输出false
System.out.println(Arrays.equals(arr, b));
System.out.println("=========================");
// 将arr数组的第3个元素(包括)到第5个元素(不包括)赋值为88
Arrays.fill(arr, 2,4,88);
// Arrays.toString()将一个数组转换成一个字符串。
System.out.println(Arrays.toString(arr));
}
}
标签:eps elf sap acm ssg wap 建立 ade DDM
原文地址:https://www.cnblogs.com/smallmin/p/9777036.html