您的位置:首页 > 职场人生

黑马程序员 java学习笔记——数组

2014-07-28 21:50 411 查看

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流!
----------------------

数组的定义

概念:同一种类型数据的集合,其实数组就是一个容器。

优点:可以自动给数组中的元素从0开始编号,方便操作这些元素。
定义数组有两种格式:

1、元素类型[] 数组名=new 元素类型[元素个数或数组长度];

示例:int[] arr=new int[5];

2、元素类型[] 数组名=new 元素类型[]{元素,元素,元素,……}

示例:int[] arr=new int[]{1,9,4,6};

int[] arr={1,9,4,6}

public class Test1 {
public static void main(String[] args){
//x是数组类型
//x[0]是int型
int[] x=new int[5];  //在堆内存中创建一个长度为5的数组
for(int i=0;i<5;i++){
System.out.print(x[i]);
}
}
}
//output:00000
//由输出结果可知,数组中的元素在未赋值时有默认值,为0
//char类型的数组,元素的默认值为'\u0000',unicode表中的空格


数组的内存分配及特点

java程序在运行时,需要在内存中的分配空间。为了提高运算效率,又对空间进行了不同区域的划分,因为每一篇区域都有特定的处理数据方式和内存管理方式。

栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。

定义在方法中的变量,定义在方法参数上的变量,定义在for循环中的变量,都是局部变量。

堆内存:数组和对象,通过new建立的实例都存放在堆内存中。

每一个实体都有内存地址值

实体中的变量都有默认初始化值

实体不在被使用,会在_不确定_的时间内被垃圾回收器回收。

内存中除了堆内存和栈内存外,还有方法区,本地方法区和寄存器。

public class Test1 {
public static void main(String[] args){
int[] arr=new int[4]; //将堆内存中的数组指向栈内存中的数组变量x。
int[] arr1=arr;  //将内存地址x传递给y
arr[0]=5;
arr1[0]=9;
arr=null; //将数组变量x清除,也就是说它不在指向堆内存中的数组
System.out.println(arr1[0]);
}
}
//output:9


上面程序的内存图如下



数组中的常见异常

1、ArrayIndexOutOfBoundsException:数组角标越界异常

如int[] arr=new int[3];

System.out.println(arr[3]);

由于这段代码不存在语法错误,并未创建数组,编译期间不会报错,但当运行时,就会报错ArrayIndexOutOfBoundsException,因为它访问到了数组中不存在的角标。

2、NullPointerException:空指针异常

如int[] arr=new int[3];

arr=null;

System.out.println(arr[3]);

当引用没有任何指向值,为null的情况,该引用还在用于操作实体,就会产生NullPointerException。

数组的常见操作

遍历

public class Test1 {
public static void main(String[] args){
//数组的操作
//获取数组中的元素,通常会用到遍历
int[] x=new int[]{68,81,35,64,22};
for(int i=0;i<x.length;i++){  //x.length为数组x的长度
System.out.println(x[i]);
}
}
}
//output:
//68
//81
//35
//64
//22


获取最值

/*
* //给定数组{68,81,35,64,22,39},获取最大值与最小值
* 思路:
1、获取最值需要进行比较。每一次比较都会有一个较大值,因为该值不确定,通过一个变量进行临时存储。
2、让数组中的每一个元素都和这个变量中的值进行比较。如果大于了变量中的值,就用该变量记录较大值
3、当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值

步骤:
1、定义变量,初始化为数组中任意一个元素即可
2、通过循环语句对数组进行遍历
3、在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量

需要定义一个功能来完成,以便提高复用性
1、明确返回值,数组中的最大元素int型
2、未知内容:一个数组,int[]

最小值与最大值的思路与步骤相似。
* */
public class Test1 {
public static void main(String[] args){
int[] x=new int[]{68,81,35,64,22,39};
System.out.println("max="+getMax(x));
System.out.println("min="+getMin(x));
}
/*
* 获取最大值
* @param arr 接收一个int型数组
* @return 返回数组中的最大值
* */
public static int getMax(int[] arr){
int max=arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>max)
max=arr[i];
}
return max;
}
/*
* 获取最小值
* @param arr 接收一个int型的数组
* @return 返回数组中的最大值
* */
public static int getMin(int[] arr){

//将min定义为数组的角标,而不是元素。
int min=0;
for(int i=1;i<arr.length;i++){
if(arr[i]<arr[min])
min=i;
}
return arr[min];
}
}
//output:
//max=81
//min=22


排序:选择排序和冒泡排序

import java.util.Arrays;
public class Test1 {
public static void main(String[] args){
int[] x=new int[]{68,81,35,64,22,39};
System.out.println(Arrays.toString(x));
selectSort(x);
System.out.println(Arrays.toString(x));
bubbleSort(x);
System.out.println(Arrays.toString(x));
}

//选择排序
//第一圈时,最值出现在第一位
public static void selectSort(int[] arr){   //x指向堆中对象,操作对象,此处不用返回值。
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);
}
}
}
}

//冒泡排序
//第一圈时,最值出现在最后位
public static void bubbleSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]<arr[j+1]){
swap(arr,j,j+1);
}
}
}
}
public static void swap(int[] arr,int a,int b){  //位置置换功能的抽取
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
}
//output:
//[68, 81, 35, 64, 22, 39]
//[22, 35, 39, 64, 68, 81]
//[81, 68, 64, 39, 35, 22]


折半查找

public class Test1 {
public static void main(String[] args){
int[] x=new int[]{68,81,35,64,22,39};
int index=getIndex(x,35);
System.out.println(index);

}
/*
*当数组按照顺序排列时,折半查找某一个数
* @param arr key 接收一个int型数组和一个int型数值
* @return 返回一个int型值
*/
public static int halfSearch_2(int[] arr,int key){
int min=0,max=arr.length-1,mid;
while(min<=max){
mid=(min+max)>>1;
if(key>arr[mid])
min=mid+1;
if(key<arr[mid])
max=mid-1;
else
return mid;
}
return -1;
}
/*
* 当数组按照顺序排列时,折半查找某一个数
* @param arr key 接收一个int型数组和一个int型数值
* @return 返回一个int型值
* */
public static int halfSearch_1(int[] arr,int key){
int min=0,max=arr.length-1,mid=(min+max)/2;
while(key!=arr[mid]){
if(key>arr[mid])
min=mid+1;
else if(key<arr[mid])
max=mid-1;
if(min>max)
return -1;
mid=(min+max)/2;
}
return mid;
}
/*
* 获取key第一次出现在数组中的位置
* @param arr key 接收一个int型数组和一个int型值
* @return 返回值为int型值
* */
public static int getIndex(int[] arr,int key){
for(int i=0;i<arr.length;i++){
if(key==arr[i])
return i;
}
return -1;
}
}
折半查找的前提是数组是有序的。

进制转换:查表法

/*
* 用查表法将十进制转换成二进制、八进制、十六进制
* 经过抽取,从三个方法中抽取出trans方法,表就放在其中。其他三个方法只需要调用它既可
* */
public class Test1 {
public static void main(String[] args){
//toBin(6);
//toHex(-60);
toOct(18);
}
/*
* 将十进制转换成八进制
* @param num 接收int型数值
* */
public static void toOct(int num){
trans(num,7,3);
}
/*
* 将十进制转换成二进制
* @param num 接收int型数值
* */
public static void toBin(int num){
trans(num,1,1);
}
/*
* 将十进制转成十六进制
* @param num 接收int型数值
* */
public static void toHex(int num){
trans(num,15,4);
}
/*
* 从toBin、toOct、toHex中抽取出来的方法,查表法的凝结精华。
* @param num base offset 接收三个int型数值
* */
public static void trans(int num,int base,int offset){
char chs[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char arr[]=new char[32];
int pos=arr.length;
while(num!=0){
int temp=num&base;
arr[--pos]=chs[temp];
num=num>>>offset;
}
for(int i=pos;i<arr.length;i++){
System.out.print(arr[i]+"");
}
}
}


二维数组

定义二维数组的两种格式

格式1:int[][] arr=new int[3][2];

定义了名称为arr的二维数组

二维数组中有3个一维数组

每一个一维数组中都有2个元素

一维数组的名称分别为arr[0]、arr[1]、arr[2]

给第一个一维数组1角标位赋值为78,写法是:arr[0][1]=78

格式2:int[][]=new int[3][];

二维数组中有3个一维数组

每一个一维数组都是默认初始化值null

可以对这三个一维数组分别进行初始化

arr[0]=new int[3];

arr[1]=new int[1];

arr[2]=new int[2];

public class Test1 {
public static void main(String[] args){
int[][] arr=new int[3][4];//定义了名称为arr的二维数组,二维数组中有3个一维数组
//每一个一维数组中有4个元素

System.out.println(arr);  //output:[[I@1db9742
System.out.println(arr[0]); //[I@106d69c
System.out.println(arr[0][1]); //0

int[][] arr1=new int[3][];
System.out.println(arr1); //[[I@52e922
System.out.println(arr1[0]); //null::::这个才是重点
//由于arr1[0]没有初始化,所以它是默认初始化。数组是引用数据类型,所以为null

arr1[0]=new int[3];
arr1[1]=new int[1];
arr1[2]=new int[2];
System.out.println(arr1[0]);//[I@25154f
System.out.println(arr1.length);//3     //打印的是二维数组的长度
System.out.println(arr1[0].length);//3	 //打印二维数组中第一个一维数组长度
}
}


二维数组的求和

public class Test1 {
public static void main(String[] args){
int[][] arr={{16,43,52,1},{24,10,32},{2,91,34,55,61,33}};
int sum=0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
sum=sum+arr[i][j];
}
}
System.out.println("sum="+sum);
}
}
//output:sum=454


二维数组的小练习:判断正误

小练习:

一维数组的定义方式:int[] x;int x[]

二维数组的定义方式:int[][] x;int x[][];int[] x[];

——————————————————————————

int[] x,y[];x是一维,y是二维

拆开来就是这样int[] x ;int[] y[]

——————————————————————————

a.x[0]=y//error

b.y[0]=x//yes

c.y[0][0]=x//error

d.x[0][0]=y//error

e.y[0][0]=x[0]//yes

f.x=y//error

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流!
----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: