数组

来源:互联网 发布:数据化人生.txt 编辑:程序博客网 时间:2024/05/17 05:05

一、数组的一些特点

1、数组是一个有界的线性序列,大小被固定、随机访问速度非常快(超过集合);
2、数组可以存储基本类型,也可以存储引用类型;
3、数组如果没被初始化则为null,数组如果没被显式初始化,则会自动初始化。其中的值与数组元素类型的默认初始化值相同;
4、数组可以有多维的,但是,一维数组要比多维的快很多。在对效率要求很高的程序中,一般都不用多维数组,需要用的时候,也常常将多维数组转换为一维的存储方式;
5、数组的声明不能使用泛型,其实也没必要在数组上使用泛型;
二、数组的初始化
1、系统默认自动初始化
比如int[] a = int[3]; 实际上与int[] a= {0,0,0}相同。
如果是引用类型则其中自动初始化为null值。
2、显式指定初始化
int[] a= {0,0,0};
int[][] a1 = {{1,2,3},{4,5,6}};
3、使用工具初始化
int[] c = new int[3];
Arrays.fill(c,3);
三、java.util.Arrays
Arrays类是一个非常有用数组工具类,里面有很多工具方法,检索、填充、排序、比较、toString()等。
下面给个例子:
import java.util.Arrays;/** * 数组综合测试 */public class TestArrays {public static void main(String[] args) {int[] i = new int[10];// 填充数组Arrays.fill(i, 2);// 遍历数组for (int x : i) {System.out.print(x + " ");}// toString()数组System.out.println("\n" + Arrays.toString(i));// 复制数组int[] b = new int[12];System.arraycopy(i, 0, b, 2, 5);System.out.println(Arrays.toString(b));// 一维数组的比较int[] c = new int[3];int[] d = new int[3];Arrays.fill(c, 3);Arrays.fill(d, 3);System.out.println(c.equals(d));System.out.println(Arrays.equals(c, d));System.out.println("-------------");int[][] a1 = { { 1, 2, 3 }, { 4, 5, 6 } };int[][] a2 = { { 1, 2, 3 }, { 4, 5, 6 } };System.out.println(a1.equals(a2));System.out.println(Arrays.equals(a1, a2));System.out.println(Arrays.deepEquals(a1, a2));// 深度toString()System.out.println(Arrays.toString(a1));System.out.println(Arrays.deepToString(a1));// 数组的排序int[] a3 = { 3, 2, 5, 4, 1 };System.out.println(Arrays.toString(a3));Arrays.sort(a3);System.out.println(Arrays.toString(a3));// 一维数组数值检索int index1 = Arrays.binarySearch(a3, 4);int index2 = Arrays.binarySearch(a3, -12);int index3 = Arrays.binarySearch(a3, 8);System.out.println(index1 + " " + index2 + " " + index3);}}




执行结果:
2 2 2 2 2 2 2 2 2 2 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2] [0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0] false true ------------- false false true [[I@3e25a5, [I@19821f] [[1, 2, 3], [4, 5, 6]] [3, 2, 5, 4, 1] [1, 2, 3, 4, 5] 3 -1 -6 


四、数组的复制
java.lang.System
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
参数:
src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
具体用法参看上例。

五、补缺

1、数组的长度:数组名.length;
2、数组元素的访问:数组名[index],或数组名[index1][index2];
六、Array类
java.lang.reflect.Array 提供了动态创建和访问 Java 数组的方法。
java.sql.Array SQL 类型 ARRAY 在 Java 编程语言中的映射关系。
七、陷阱
1、填充数组,Arrays.fill()方法只能填充一维基本类型数组。
2、数组复制,不但适合一维数组,也适合多维数组,只是多维数组赋值时候要特别小心,有时候会出一些莫名其妙的问题
int[][] a1 = {{1, 2, 3}, {4, 5, 6}}; int[][] ax = newint[3][3];System.arraycopy(a1,1,ax,1,1); System.out.println(Arrays.deepToString(ax));

输出结果:
[[0, 0, 0], [4, 5, 6], [0, 0, 0]]
如果改为:
int[][] a1 = {{1, 2, 3}, {4, 5, 6}}; int[][] ax = newint[2][4]; System.arraycopy(a1,0,ax,0,1); int[] x1 = ax[0]; System.out.println("二维数组第一个元素的长度:"+x1.length);System.out.println("-----"); for (int[] t : ax) {for (int _i : t) {System.out.println(_i); } System.out.println("-----"); }

输出结果:
二维数组第一个元素的长度:3 ----- 1 2 3 ----- 0 0 0 0 -----


这个结果看起来就太迷惑了!
3、数组的排序,只能排序基本类型数组,如果是其他类型,可以考虑使用集合工具Collections来做。
4、尽可能不要使用多维数组,多维数组效率会有很大的损失。



JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡法、选择排序法、插入排序法。

快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现。

冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。

选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。

插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。下面我就将他们的实现方法一一详解供大家参考。

<1>利用Arrays带有的排序方法快速排序
import java.util.Arrays; public class Test2{         public static void main(String[] args){                 int[] a={5,4,2,4,9,1};                 Arrays.sort(a);  //进行排序                 for(int i: a){                         System.out.print(i);                 }         } }

<2>冒泡排序算法
public static int[] bubbleSort(int[] args){//冒泡排序算法                 for(int i=0;i<args.length-1;i++){                         for(int j=i+1;j<args.length;j++){                                 if (args[i]>args[j]){                                         int temp=args[i];                                         args[i]=args[j];                                         args[j]=temp;                                 }                         }                 }                 return args;         }

<3>选择排序算法
public static int[] selectSort(int[] args){//选择排序算法                 for (int i=0;i<args.length-1 ;i++ ){                         int min=i;                         for (int j=i+1;j<args.length ;j++ ){                                 if (args[min]>args[j]){                                         min=j;                                 }                         }                         if (min!=i){                         int temp=args[i];                         args[i]=args[min];                         args[min]=temp;                                 }                 }                 return args;         }

<4>插入排序算法
public static int[] insertSort(int[] args){//插入排序算法                 for(int i=1;i<args.length;i++){                         for(int j=i;j>0;j--){                                 if (args[j]<args[j-1]){                                         int temp=args[j-1];                                         args[j-1]=args[j];                                         args[j]=temp;                                         }else break;                         }                 }                 return args;         }

最后数组的总结:
数组(array)是相同类型变量的集合,可以使用共同的名字引用它。数组可被定义为任何类型,可以是一维或多维。数组中的一个特别要素是通过下标来访问它。数组提供了一种将有联系的信息分组的便利方法。注意:如果你熟悉C/C++,请注意, Java数组的工作原理与它们不同。

1、数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。数组保存的仅仅是对象的引用,而不是对象本身。

2、数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。

3、数组声明的两种形式:一、int[] arr; 二、int arr[]; 推荐使用前者,这符合Sun的命名规范,而且容易了解到关键点,这是一个int数组对象,而不是一个int原始类型。

4、在数组声明中包含数组长度永远是不合法的!如:int[5] arr; 。因为,声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。

5、在数组构造的时候必须指定长度,因为JVM要知道需要在堆上分配多少空间。反例:int[] arr = new int[];

6、多维数组的声明。int[][][] arr; 是三维int型数组。

7、一维数组的构造。形如:String[] sa = new String[5]; 或者分成两句:String[] sa; sa = new String[5];

8、原始类型数组元素的默认值。对于原始类型数组,在用new构造完成而没有初始化时,JVM自动对其进行初始化。默认值:byte、short、 int、long--0 float--0.0f double--0.0 boolean--false char--'"u0000'。(无论该数组是成员变量还是局部变量)

9、对象类型数组中的引用被默认初始化为null。如:Car[] myCar = new Car[10]; 相当于从myCar[0]到myCar[9]都这样被自动初始化为myCar[i] = null;

10、对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。也就是说:Car[] myCar = new Car[10];只创建了一个myCar数组对象!并没有创建Car对象的任何实例!

11、多维数组的构造。float[][] ratings = new float[9][]; 第一维的长度必须给出,其余的可以不写,因为JVM只需要知道赋给变量ratings的对象的长度。

12、数组索引的范围。数组中各个元素的索引是从0开始的,到length-1。每个数组对象都有一个length属性,它保存了该数组对象的长度。(注意和String对象的length()方法区分开来,这两者没有统一起来是很遗憾的。)

13、Java有数组下标检查,当访问超出索引范围时,将产生ArrayIndexOutOfBoundsException运行时异常。注意,这种下标检查不是在编译时刻进行的,而是在运行时!也就是说int[] arr = new int[10]; arr[100] = 100; 这么明显的错误可以通过编译,但在运行时抛出!Java的数组下标检查是需要额外开销的,但是出于安全的权衡还是值得的,因为很多语言在使用数组时是不安全的,可以任意访问自身内存块外的数组,编译运行都不会报错,产生难以预料的后果!