黑马程序员--java基础复习之数组
2015-03-16 22:12
363 查看
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------</span>
在刚开始学习数据类型的时候,我们就学习过了八种基本数据类型 byte short int lang float double char boolean ,还有就是三种引用类型,第一个就是数组,以及类和接口。
首先,是数组的定义,数组是同一类型数据的集合。其实就是一个容器,就是用于存储数据的地方。数组的好处就是可以自动给数组中的元素从0开始编号,这样方便于操作元素。如同每个班里的学生都有一个学号一样,方便管理学生。
然后是数组的定义格式。
第一种:元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
例如:
int[] arr=new int[3];
这表示的是定义了一个数据类型为int,长度为3的数组,它的元素角标是从0开始的,最后一个角标为2。
第二种:元素类型[] 数组名 = new 元素类型[]{元素1,元素2,....};
例如:
int[] arr=new arr[]{5,4,16}; int[] arr1={7,5,9};上面两行代码都表示定义了一个长度为3的int类型的数组,并且都初始化了值
数组在内存中的表现形式
int [] x=new int[3];
上面这句代码在内存中是这样的,如图:
和局部变量不一样,引用型变量x是存放在栈内存中的,而数组是先分配一个地址值,然后在堆内存中开辟出一片空间,这时数组中的元素就已经有了默认初始化值。int类型默认初始化值为0,boolean 类型为false,String 类型为null.然后将这个地址值赋值给变量x,即x指向了堆内存中的这个数组。当给数组中的第一个元素x[0]赋值为59时,在堆内存中数组的第一个元素的值就修改为59,如上图。当我们将null
赋值给引用型变量x时,即 x=null时,栈内存中x的值就变成了null,就不再指向数组在堆内存的地址,那么,堆内存中的这个数组就变成没用的了,因为没有变量再指向它了,那么java就会调用垃圾回收机制来回收它了。
那么下面说栈内存和堆内存的作用和区别
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
堆内存:A、数组和对象,通过new建立的实例都存放在堆内存中。
B、每一个实体都有内存地址值。
C、实体中的变量都有默认初始化值。
D、实体不再被使用,会在不确定的时间内被垃圾回收器回收。
小细节:1、以下这两种定义数组的方式都可以,效果是一样的,推荐使用第一种
int[] arr=new int[2]; int arr1[] =new int[2];
2、静态初始化数组时,不要写长度,如下
int[] arr=new int[3]{1,8,6};
操作时常见问题
1、角标越界异常(ArrayIndexOutOfBoundsException ),如下图
其中,ArrayIndexOutOfBoundsException ,这个就是数组角标越界异常,这是因为操作数组时,访问到了数组中不存在的角标。如代码中所示,长度为3的数组,最大的角标位为2,而不是3。
2、空指针异常(NullPointerException) ,如图
当将null的值赋给arr时,arr的地址值就不再指向数组在堆内存中的位置了,所以用arr来操作数组中的元素时就会出现这个异常。NullPointerException:空指针异常,当引用没有任何指向值为null的情况,该引用还在用于操作实体。
数组的常见操作
1、数组的遍历
class ArrayDemo { public static void main(String[] args) { //数组的遍历操作:获取数组中的元素 //定义一个长度为3的数组 int[] arr=new int[3]; for(int x=0;x<3;x++) { System.out.println("arr["+x+"]="+arr[x]); } } }
定义了一个长度为3的数组,但是并没有给其中的元素赋值,结果:
可以看出,int类型数组默认初始化值为0。
数组有一个属性length,可以获取数组的长度
class ArrayDemo { public static void main(String[] args) { //数组的遍历操作:获取数组中的元素 //length:获取数组中元素的个数,使用方式:数组名.length //定义一个长度为3的数组 int[] arr=new int[]{3,5,7,13,6,88}; for(int x=0;x<arr.length;x++) { System.out.println("arr["+x+"]="+arr[x]); } } }
结果:
下例
<span style="font-size:12px;">class ArrayDemo { public static void main(String[] args) { //数组的遍历操作:获取数组中的元素 int[] arr=new int[]{3,5,7,13,6,88}; printArray(arr); } //功能:打印数组中的元素,元素间用逗号隔开 static void printArray(int[] arr) { System.out.print("["); for(int x=0;x<arr.length;x++) { if(x!=arr.length-1) //当前元素不是最后一个元素时 System.out.print(arr[x]+","); else System.out.println(arr[x]+"]"); //当遍历到最后一个元素时,不加逗号 } } }</span>结果:
2、获取数组中的最值(最大值、最小值)
<span style="font-size:12px;">/* 获取数组中的最值 给定一个数组{6,8,4,1,14,25} */ class ArrayTest2 { public static void main(String[] args) { int[] arr=new int[]{6,8,4,1,14,25}; int max=getMax(arr); System.out.println(max); } /* 需求:获取数组中的最大值,以及最小值 获取数组中的最大值 思路:1、获取最大值需要进行比较,每一次比较都会有一个较大的值。因为该值不 不确定,所以定义一个变量用来存储这个较大值。 2、通过遍历,让数组中的元素分别和这个变量的值进行比较,若值大于该变量的值,则 该变量存储这个较大的值。 3、循环完成后,所有的元素都比较完成,那么该变量存储的就是数组中的最大值了。 */ public static int getMax(int[] arr) { int max=arr[0]; //从角标1的位置开始,因为max初始化值为arr[0],所以max不用和arr[0]比较。 for(int x=1;x<arr.length;x++) { if(max<arr[x]) //若数组中的元素值大于max的当前值,则将此元素的值赋给max max=arr[x]; } return max; } }</span>
结果:
3、选择排序
原理:将数组中第一个元素同其他元素比较大小,得到最小值并放成0标上.然后继续在剩下的元素中寻找第二个最小元素,放在第二个位置。依此类推。就能得到排序结果。
代码如下
<span style="color:#666666;">class ArraySortDemo { public static void main(String[] args) { int[] arr=new int[]{5,6,4,15,25,1,8,95}; printArray(arr); //排序前 ArraySelectSort(arr); //打印数组 printArray(arr); //排序后 } /* 选择排序 */ static void ArraySelectSort(int[] arr) { //外循环遍历数组 for(int x=0;x<arr.length-1;x++) { //内循环比较大小 for(int y=x+1;y<arr.length;y++) { //定义一个第三方变量,便于元素交换位置 int temp; //若前一个元素比后一个元素大,则两元素互换位置 if(arr[x]>arr[y]) { temp=arr[x]; arr[x]=arr[y]; arr[y]=temp; } } } } //打印数组 static void printArray(int[] arr) { if(arr!=null) { System.out.print("["); //遍历数组 for(int x=0;x<arr.length;x++) { if(x!=arr.length-1) System.out.print(arr[x]+","); else System.out.print(arr[x]); } System.out.println("]"); } } }</span>输出结果:
4、冒泡排序
原理: 1、先从头角标相邻两个元素之间进行比较,取较大值存放在后一个元素中,然后再与后一个元素的进行比较,直至最大值存放到最后一个元素中。
2、再重复1操作,每次计较次数减一,一圈比完后存放的较大元素不再参与比较。
代码如下:
class ArraySortDemo { public static void main(String[] args) { int[] arr=new int[]{5,6,4,15,25,1,8,95}; printArray(arr); //排序前 ArrayBubbleSort(arr); //打印数组 printArray(arr); //排序后 } //对数组冒泡排序 //从角标0开始,相邻两个元素进行比较,符合条件就互换位置,每轮下来,最值出现在数组最后一个位置上。 //依此类推,每轮要比较的个数少一个。 static void ArrayBubbleSort(int[] arr) { for(int x=0;x<arr.length-1;x++) { for(int y=0;y<arr.length-(x+1);y++) { if(arr[y]>arr[y+1]) { int temp; temp=arr[y]; arr[y]=arr[y+1]; arr[y+1]=temp; } } } } //打印数组 static void printArray(int[] arr) { if(arr!=null) { System.out.print("["); //遍历数组 for(int x=0;x<arr.length;x++) { if(x!=arr.length-1) System.out.print(arr[x]+","); else System.out.print(arr[x]); } System.out.println("]"); } } }
结果:
5、折半查找(两种折半方式,及一个整数返回插入有序数组后的位置)
class ArrayTest { public static void main(String[] args) { int[] arr={5,6,1,4,8,7,14,23}; int[] arr1={2,4,6,7,9,10,15,25,725}; //int index=getIndex(arr,14); //折半查找一 int index=halfSearch(arr,22); //折半查找二 int index1=halfSearch_1(arr,22); //向有序数组中插入一数,得到该数的角标位置 int index2=halfSearch_2(arr1,22); System.out.println(index+":"+index1+":"+index2); } /* 折半查找:提高效率,但是必须保证该数组是有序的数组。 第一种 */ static int halfSearch(int[] arr,int key) { int min,mid,max; min=0; max=arr.length-1; mid=(min+max)/2; while(arr[mid]!=key) { if(arr[mid]>key) { max=mid-1; } else { min=mid+1; } mid=(min+max)/2; if(min>max) return -1; } return mid; } /* 折半查找 第二种方式 */ public static int halfSearch_1(int[] arr,int key) { int min=0,max=arr.length-1,mid; while(arr[min]<=arr[max]) { mid=(min+max)>>1; //等同于除以2 if(arr[mid]>key) max=mid-1; else if(arr[mid]<key) min=mid+1; else return mid; } return -1; } /* 向一个有序的数组中插入一个数,插入后该数组依然是有序的 原理:折半查找后,返回-1改成返回min的值,即是此数插入后的角标位置 两种方式的结果一样 */ public static int halfSearch_2(int[] arr,int key) { int min=0,max=arr.length-1,mid; while(arr[min]<=arr[max]) { mid=(min+max)>>1; //等同于除以2 if(arr[mid]>key) max=mid-1; else if(arr[mid]<key) min=mid+1; else return mid; } return min; } //从数组中查找某元素 //参数:int类型数组,int类型元素 static int getIndex(int[] arr,int key) { if(arr!=null) { for(int x=0;x<arr.length;x++) { if(arr[x]==key) return x; } return -1; } return -1; } }
结果:
6、进制转换
代码如下:
class ArrayTest1 { public static void main(String[] args) { toBin(6); toHex(60); toHexBySearch(60); trans(60,15,4); } //十进制---->二进制 static void toBin(int num) { //定义一个字符串缓存,用于存储转换结果 StringBuffer sb=new StringBuffer(); while(num>0) { sb.append(num%2); num=num/2; } System.out.println(sb.reverse()); } //十进制转十六进制 static void toHex(int num) { //定义一个字符串缓存,用于存储转换结果 StringBuffer sb=new StringBuffer(); for(int x=0;x<8;x++) { int temp=num&15; if(temp>9) sb.append((char)(temp-10+'A')); else sb.append(temp); num=num>>>4; } //使用字符串缓存的反转功能,输入结果的正确顺序 System.out.println(sb.reverse()); } /* 查表法:将所有的元素临时存储起来。建立对应关系。 */ static void toHexBySearch(int num) { char[] ch=new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] arr=new char[8]; int pos=arr.length; while(num!=0) { int temp=num&15; arr[--pos]=ch[temp]; num=num>>>4; //System.out.println(arr[pos]); } for(int x=pos;x<arr.length;x++) { System.out.print(arr[x]+","); } System.out.println(); } //进制转换 //参数:要转换的数据,与的基数,偏移位数 static void trans(int num,int base,int offset) { if(num==0) { System.out.println(0); return; } //通用查表数组 char[] ch=new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; //最大长度是二进制的32位 char[] arr=new char[32]; int pos=arr.length; //通过循环,倒序的方式向数组中插入 while(num!=0) { int temp=num&base; arr[--pos]=ch[temp]; num=num>>>offset; } //从数组中实际位置开始输出(即第一个不为0的位置) for(int x=pos;x<arr.length;x++) { System.out.print(arr[x]); } } }
二维数组
数组中的数组
形象比喻:以前的一维数组,就如同一个箱子,箱子里面有很多小格子,每一个小格子用于存放一个元素,箱子里格子的个数即是数组的长度。现在有一个大箱子,里面放的不是小格子,而是一个个里面有很多小格子的箱子。这个大箱子就是二维数组。而这个大箱子里小箱子的个数即为这个二维数组的长度
二维数组的定义格式
int[][] arr=new int[2][4];
这行代码的意思是定义一个名称为arr的二维数组,二维数组里有两个一维数组,每个一维数组的长度为4;
int[][] arr=new int[2][];
这句代表定义了一个名称为arr的二维数组,里面有两个一维数组,每个一维数数的初始化值为null
int[][] arr={{2,4},{4,5,6},{44,8,2}};
定义一个名为arr的二维数组,该数组长度为3,其中的元素分别为{2,4},{4,5,6},{44,8,2}三个一维数组。
如下图,为二维数组与一维数组之间的关系判断
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!
-------
相关文章推荐
- 黑马程序员——Java基础 数组 (复习)
- 黑马程序员-----java基础③(数组及循环练习)
- 黑马程序员 JAVA基础 数组、数组工具类、文档注释总结
- 黑马程序员_Java基础(流程控制、函数、数组)
- 黑马程序员 Java基础<一> 数组及排序
- 黑马程序员__JAVA基础__数组
- 黑马程序员JAVA基础-数组的操作
- Java基础复习笔记 数组,内存形式,父子,内存控制01
- 黑马程序员——java编程那些事儿____java基础(三) 数组
- Java基础复习——数据类型、变量和数组
- 黑马程序员:java基础学习——数组
- 黑马程序员 java基础 函数 数组 查找与排序总结
- 黑马程序员-(5)Java基础语法之数组
- 黑马程序员---Java基础--04天(数组)
- 黑马程序员_java初级基础知识汇总(常量和变量、语句、函数、数组)
- 【黑马程序员】-Java基础语法(数组) 第四天
- 黑马程序员--Java基础之语法和数组总结
- 黑马程序员JAVA基础-数组以及一些基本操作
- 黑马程序员 java基础之数组
- 黑马程序员_java基础二(语句,函数method和数组Array)