天天看点

黑马程序员_java基础--数组

 ------- <a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">android培训</a>、<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">java培训</a>、期待与您交流! ----------

数组初始化:

    Java中数组必须经过初始化才可以使用,而java的数组是静态的,所以数组初始化以后数组的长度是不可以变的。

所谓初始化,就是为数组对象的元素分配内存空间,并为每个数组元素指定初始值。

数组的初始化有2中方式:

1、静态初始化:初始化时由程序员显示指定每个数组元素的初始值,由系统决定数组长度。

2、动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。

不管采用哪种方式初始化,一旦数组初始化完成,数组的长度是不可以变的。

示例如下:

public class ArrayDemo {
	public static void main(String args[]){
		//采用静态初始化方式初始化第一个数组
		int[] x1 = new int[]{1,2,3,4};
		System.out.println("静态初始化方式初始化第一个数组:");
		printArray(x1);
		
		//采用静态初始化方式初始化第二个数组
		int[] x2 ={1,2,3,4};
		System.out.println("静态初始化方式初始化第二个数组:");
		printArray(x2);
		
		
		//采用动态初始化方式初始化数组
		int[] x3 = new int[4];
		for(int i = 0; i<4; i++){
			x3[i] = i;
		}
		System.out.println("动态初始化方式初始化数组:");
		printArray(x3);
		
	}
	//打印数组
		public static void printArray(int[] x){
			System.out.print("[");
			for(int i=0; i< x.length;i++){
				if(i == x.length-1)
					System.out.print(x[i]);
				else
					System.out.print(x[i]+",");
			}
			System.out.println("]");
		}

}
           

在执行动态初始化时,只需要指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。

指定初始值时,系统将按照如下规则分配初始值:

   数组元素的类型时基本数据类型中的整数类型(byte、short、int和long),则数组元素的值是0。

   数组元素的类型时基本数据类型中的浮点类型(float、double),则数组元素的值是0.0。

   数组元素的类型时基本数据类型中的字符类型(char),则数组元素的值是'\u0000'。

   数组元素的类型时基本数据类型中的布尔类型(boolean),则数组元素的值是false。

   数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null。

注意:不要同时使用静态初始化和动态初始化,即不要在进行数组初始化时,既指定数组的长度,也为每个数组元素分配初始值。

数组一定要初始化吗?

记住:

Java的数组变量是引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中就可以使用该数组变量。

示例:

class ArrayTest2{
public static void main(String args[]){
	//定义并初始化数组
	int[] nums = new int[]{3,5,20,12};
	//定义一个prices数组变量
	int[] prices;
	//让prices数组指向nums所引用的数组
	prices = nums;
	for(int i=0; i<prices.length; i++){
		System.out.println(prices[i]);
	}
	//将prices数组的第三个元素赋值为23
	prices[2] = 23;
	//访问nums数组的第三个元素,将看到输出23
	System.out.println("nums数组的第三个元素的值是:"+nums[2]);
     }
}
           

结论:这会不会和使用java数组之前一定要进行初始化矛盾呢?

       其实,这并不矛盾。关键是大部分的时候,我们把数组变量和数组对象搞混了,数组变量只是一个引用变量,通

常存放在栈内存中(也可以放入堆内存中),而数组对象就是保存在堆内存中的连续内存空间。对数组执行初始化,其

实并不是对数组变量执行初始化,而是要对数组对象执行初始化------也就是为该数组对象分配一块连续的内存空间,这

块连续的内存空间的长度就是数组的长度。虽然上面程序中的prices变量看似没有进过初始化,但执行prices = nums;

就会让prices变量直接指向一个已经执行初始化的数组。

对于数组变量来说,它并不需要进行所谓的初始化,只要让数组变量指向一个有效的数组对象,程序就可以正常使用该数组变量。

对于java程序中所有的引用变量,它们都不需要进过所谓的初始化操作,需要进行初始化操作的是该引用变量所引用的对象。

引用类型数组的初始化:

引用类型数组的数组元素依然是引用引用类型的,因此数组元素里存储的还是引用,它指向另一块内存里存储了该引用变量所引用的对象(包括数组和java对象)。

用下面的程序说明:

class Person{  //定义一个Person类
	int age;
	double height;
	void info(){
		System.out.println("我的年龄是:"+age+",我的身高是:"+height);
	}
}

public class ArrayTest3 {
	public static void main(String args[]){
		Person[] students;          //定义一个Person[]数组
		students = new Person[2];   //动态初始化数组
		
		Person zhang = new Person();  //创建一个Person实例。并赋值给zhang
		zhang.age = 20;
		zhang.height = 180.0;         //为Person对象的属性赋值
		students[0] = zhang;	    //将zhang变量的值赋值给第一个数组元素
		
		Person Lee = new Person();     //创建一个Person实例。并赋值给Lee
		Lee.age = 22;
		Lee.height = 175.0;           //为Person对象的属性赋值
		students[1] = Lee;	    //将Lee变量的值赋值给第一个数组元素
		
		Lee.info();
		students[1].info();       //这2中方式的执行结果一样,因为Lee和students[1]指向的是同一个Person实例
	}
}
           
Person[] students;
           

这行代码仅仅在栈内存中定义了一个引用变量,也就是一个指针,这个指针并未指向任何有效的内存区。

此时内存中的存储如图:

黑马程序员_java基础--数组
students = new Person[2];
           

这是对students数组执行动态初始化,由系统为数组元素分配默认的初始值null,内存中的存储如图:

黑马程序员_java基础--数组

然后程序定义了2个引用变量zhang和Lee,让它们指向堆内存中的2个Person对象。

Person zhang = new Person();
Person Lee = new Person();
           

然后为这两个Person对象的属性赋值。这时在内存中的存储如图:

黑马程序员_java基础--数组
students[0] = zhang;
students[1] = Lee;
           

这两句将zhang和Lee变量的值分别赋给students数组的第一个和第二个元素,这时内存的存储如图所示:

黑马程序员_java基础--数组

从上图可以看出:此时Lee和students[1]指向同一个内存区,而且它们都是引用类型变量,因此通过Lee和students[1]来访问Person实例的属性和方法的效果都是一样的。

不论修改studetns[1]所指向的Person实例的属性,还是修改Lee变量所指向的Person实例的属性,所修改的都是同一个内存区,所以结果必然一样。

折半查找:

public static int halfSearch(int[] arr,int key){
	int min,max,mid;
	min = 0;
	max = arr.length-1;
	mid = (max+min)/2;
	while(arr[mid]!=key){
		if(key>arr[mid])
		        min = mid + 1;
		else if(key<arr[mid])
			max = mid - 1;
		if(min>max)
			return -1;
		mid = (max+min)/2;
	}
	return mid;
}<span style="color:#ff0000;">
</span>
           

------- <a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">android培训</a>、<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">java培训</a>、期待与您交流! -----------