数组

一、数组的一些特点

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的数组下标检查是需要额外开销的,但是出于安全的权衡还是值得的,因为很多语言在使用数组时是不安全的,可以任意访问自身内存块外的数组,编译运行都不会报错,产生难以预料的后果!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值