黑马程序员——Java语言基础之数组
------Java培训、Android培训、iOS培训、.Net培训 、期待与您交流! -------
八、数组
1、定义:同一种数据类型的集合,其实质就是一个容器。
2、好处:自动给数组的元素从0开始编号,方便操作。
3、格式1: 元素类型[ ] 数组名= new 元素类型 [元素的个数或者数组的长度] ;
eg:int [ ] arr= new int[4]; 在内存中的存储结构如下:
注意: int [ ] x代表在栈内存中定义数组类型x;new代表在内存中产生一个容器实体,只要new就会产生开辟一个新的空间;int [] x=new int[4]中的”=“代表把堆内存的首地址赋值给x或者说是x引用这个数组的。
格式2: 元素类型[ ] 数组名= new 元素类型{元素,元素,.......} ;
eg:int arr[]=new int[ ] {3,1,5,7} ; int arr[]={3,1,5,7};4、栈和堆
栈内存:数据使用完毕会自动释放,栈存放的是局部变。局部变量包括定义在方法中的变量,定义在方法中参数上的变量和for循环里的变量。堆内存:new出来的实体或是对象。堆内存的特点:1)、每个实体都有内存地址值;2)、实体的数据都有默认初始值;3) 、垃圾回收机制。垃圾回收机制GC:C++程序员需要手动调用功能清除垃圾,而在java中只要实体变成垃圾,虚拟机便会自动启动垃圾回收机制,将堆内存中不在使用的实体清除掉,而这种清除会不定时间处理。5、数组中常遇到的问题
1)、.数组下标越界异常:访问到数组中不存在的角标,java.lang.ArrayIndexOutOfBoundsException;2)、空指针异常:当引用没有任何指向值时,即数组值为NULL,该引用还用于操作实体,java.lang.NullPointerException6、数组的操作
1)、获取数组中的元素,通常会用到遍历,用for循环遍历;2)、数组长度:数组名.length;3)、数组获得最大最小值;7、数组的排序方法
1)、选择排序:思想:找最小值或者是最大值的元素放在首位,以此类推。时间复杂度O(n*n),空间复杂度(1),排序过程如下:核心算法:2)、冒泡排序:/** 选择排序 1、选择排序传递的是引用类型的数组,改变的是堆内存,所以是无返回值类型void; 2、参数列表:传递要排序的数组。 */ public static void SelectSort(int[] arr){ for(int i=0;i<arr.length-1;i++){ for(int j=i+1;j<arr.length;j++){ if (arr[i]>arr[j]) // ‘>’代表从小到大排序,‘<’代表从大到小排序 { int temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } } } }
思想:相邻两个元素进行比较,如果符合条件换位。时间复杂度O(n*n),空间复杂度(1),排序过程如下:核心算法: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++){ //-i:让每一次比较元素减少,-1:避免角标越界 if (arr[j]>arr[j+1]) // ‘>’代表从小到大排序,‘<’代表从大到小排序 { int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } }
8、数组的查找
1)、线性查找:思 想: 从表头开始,依次将每一个值与目标元素进行比较,找到返回其下标,如果到表尾还是没有找到返回-1,表示查找失败;核心算法代码如下:2)、折半查找:能提高代码的执行效率,但要求代码有序。/**定义一个功能:查找数组的值 1、返回值为:int 找到返回元素元素所在的下标,不存在返回-1 2、参数列表:传递数组和要查找的值 */ public static int arrCheck(int[] arr ,int key){ for(int i=0;i<arr.length;i++){ if(arr[i]==key){ return i; //返回第一次出现key值的位置 } } return -1; }
思 想:首先,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置 记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表,重复以上过程,直到找到满足条件的记录,使查找成功,或直到 子表不存在为止,此时查找不成功。核心代码如下:/** 二分查找:可以提高查找的效率,但是要求数组有序 1、返回值类型:int 找到返回数组下标,没找到返回-1; 2、参数列表:传递数组和要查找的数值。 */ public static int halfSearch(int[] arr,int key){ int min=0,max=arr.length-1,mid; while (min<=max) // min<=max代表要使最大值和最小值有距离 { mid=(min+max)/2; if(arr[mid]<key){ //如果中间值小于要找的值则要修改min下标 min=mid+1; }else if(arr[mid]>key){ //如果中间值大于要找的值则要修改max下标 max=mid-1; }else{ return mid; } } return -1; }
9、进制之间的转换
1)、十进制转化成二进制核心代码如下:2)、十进制转换成十六进制:/** 十进制转化为二进制 */ public static void toBin(int num){ StringBuffer sb= new StringBuffer(); //定义StringBuffer容器来存储转换的之后的数 while(num>0){ sb.append(num%2); //把余数装到sb的容器中 num=num/2; //做除二运算 } System.out.println(sb.reverse()); //f通过reverse()的方法,逆序输出 }
思想:通过查表法,将所有的元素通过数组存临时存储起来,建立对应关系。每一次&15之后的值作为索引去查建立好的表,就可以找对应的元素,要比-10+‘A’简单很多。本方法不管是正数还是负数都可以通过此方法操作求取十六进制。
核心代码的实现过程:3)、通过查表把十进制转化成二进制代码核心代码如下:/** 通过查表法获得十六进制 */ public static void toHex_2(int num){ //先建立一个字符数组把十六进制的字符存储起来 char[] chs={'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] =chs[temp]; //将查找到的数据存放在数组当中 num=num>>>4; } for(int i=pos;pos<arr.length;pos++){ System.out.print(arr[pos]);//输出数据 } }
/** 通过查表法转化成二进制 */ public static void toBin_2(int num){ //定义一个二进制的表 char[]chs={'0','1'}; //定义一个临时存储容器 char[] arr=new char[32]; //定义指针来存取数组里的数 int pos=arr.length; while(num!=0){ int temp=num&1; //查表存储在临时表里面 arr[--pos]=chs[temp]; //右移一位 num=num>>>1; } for(int i=pos;i<arr.length;i++){ System.out.print(arr[i]); } }
10、二维数组:把数组作为一个元素,存到数组当中,称之为二维数组
1)、格式1:int[][] arr = new int[2][3];含义:一维数组中有2个一维数,每一个一维数组中有3个元素,一维数组的名称分别为arr[0], arr[1], arr[2]。存储结构:
2)、格式2:int[][] arr = new int[3][];
含义:二维数组中有3个一维数组,每个一维数组都是默认初始化值null,可以对这个三个一维数组分别进行初始化。
存储结构:
3)、格式3:int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};含义: 每一个一维数组中具体元素也都已初始化,第一个一维数组arr[0] = {3,8,2};,第二个一维数组arr[1] = {2,7};,第三个一维数组arr[2] = {9,0,1,6};,第三个 一维数组的长度表示方式:arr[2].length应用:二维数组的求和,核心代码如下:public class ArrayRep { public static void main(String[] args){ //用格式三初始化数组 int [][] arr={{1,2,3,4},{5,6},{7,8,9,10}}; int sum=0; for(int i=0;i<arr.length;i++){ //行数组 for(int j=0;j<arr[i].length;j++){ //列数组 sum+=arr[i][j]; //求和 } } System.out.println("sum="+sum); } }