---------------------- android培训、java培训、期待与您交流! ----------------------
数组的格式:回顾第一种格式:
int[] arr=new int[3];//arr是array的缩写。
也可以这样写:int arr[]=new int[3];推荐上面的规范写法。
第二种格式:元素类型[] 数组名=new 元素类型[]{ 元素,元素,……};比如:int[] arr=new int[]{3,1,6,5,4};也可以简化写成:int[] arr={3,1,6,5,4,};
数组的常见问题:
1.数组角标越界异常:
int[] arr=new int[3];
System.out.println(arr[3]);
编译的时候不会报错,因为只是检查语法错误,在运行的时候就会提示ArrayIndexOutOfBoundsException,意思是数组角标越界异常,数组在操作中访问到了不存在的角标。原因是在arr这个数组中有三个元素,角标分别是0,1,2,而没有3号角标,所以运行会报错。
2.空指针异常:
int[] arr=new int[3];
arr=null;
System.out.println(arr[1]);
同样是在运行的时候报错,提示NullPointerException,意思是空指针异常,因为引用没有任何指向,但引用还在操作实体。
数组的操作:
获取数组中的元素是数组最常见的操作。一般是用遍历的方式。
class Test{
public static void main(String[] args)
{
int[] arr=new int[3];
for(int x=0;x<3;x++)
{
System.out.println("arr["+x+"]="+arr[x]);
}
}
}
假如数组中的元素非常多,无法确定元素个数,此时需要用到length,这个参数可以直接获取数组中元素的个数,使用格式:数组名称.length,比如:
class Test{
public static void main(String[] args)
{
int[] arr={1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,1,1,1,1,1};
System.out.println("length="+arr.length);
for(int x=0;x<arr.length;x++)
{
System.out.println("arr["+x+"]="+arr[x]);
}
}
}
同样可以求和:
class Test
{
public static void main(String[] args)
{
int[] arr=new int[]{1,2,3,4,5,6,7,8,9,};
int sum=0;
for(int x=0;x<arr.length;x++)
{
sum+=arr[x];
}
System.out.println(sum);
}
}
应用举例:
1.打印数组中的元素,元素间用逗号隔开。
class Test
{
public static void main(String[] args)
{
int[] arr={1,2,3,4,5};
printArr(arr);
printArr(arr);
}
public static void printArr(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]+"]");
}
}
}
}
注意:如果输入System.out.println(arr);结果会显示,[I@6bade9,其中中括号表示是数组,大写i表示int,@后面的就是这个数组在堆内存中的十六进制地址,是一个用哈希算法算出的哈希值。
2.求最值:
/*
需求:获取数组中的最大值。
思路:
1.获取最值需要进行比较,每次比较都会有一个较大值,因为值不确定,需要通过一个变量进行临时存储。
2.让数组中每一个元素都和这个变量中的值进行比较。如果大于变量中的值,就替换掉变量中的值。
3.当所有元素都比较完成,那么变量中的值就是最大值了。
步骤:
1.定义变量,初始化为数组中的任意一个元素即可。
2.通过循环语句对数组进行遍历。
3.在遍历中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给变量。
需要定义一个功能来完成。
1.结果明确,数组中的最大元素,int。
2.有未知内容,一个数组,int[]。
*/
class Test
{public static int getMax(int[] arr)
{
int max=arr[5];
for(int x=0;x<arr.length;x++)
{
if(arr[x]>max)
{
max=arr[x];
}
}
return max;
}
public static void main(String[] args)
{
int[] arr={2,5,8,4,7,10};
int a=getMax(arr);
System.out.println(a);
}
}
最小值同理。求最值另一个方法:就是初始化为角标,而不是数组中的任意一个数。
class Test
{
public static int getMax(int[] arr)
{
int max=0;
for(int x=1;x<arr.length;x++)
{
if(arr[x]>arr[max])
{
max=x;
}
}
return arr[max];
}
public static void main(String[] args)
{
int[] arr={2,5,8,4,7,10};
int a=getMax(arr);
System.out.println(a);
}
}
如果是获取double类型的最值,由于函数的功能都是求最值,所以以重载的方式定义函数:
public static double getMax(double[] arr);
2.对给定数组排序:
1.选择排序:把数组中的第一个数和其他数依次比较,可以确定出整个数组的最值,然后在把第二位的数和剩下的数依次比较,就可以确定余下数组的最值,然后一直比到最后.
class Test
{
public static void selectSort(int[] arr)//没有返回值,所以是不确定。
{
for(int x=0;x<arr.length-1;x++)//最后一次比较没有必要,所以是x<arr.length-1。
{
for(int y=x+1;y<arr.length;y++)//注意写法,y每次都是比x大1,所以不要定义成常量,定义成随x变化的变量。内循环结束一次,最值出现在头角标位.
{
if(arr[x]>arr[y])//如果是降序排序,只需改成>即可.
{
arr[x]=arr[x]^arr[y];
arr[y]=arr[x]^arr[y];
arr[x]=arr[x]^arr[y];
}
}
}
}
public 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]+"]");
}
}
}
public static void main(String[] args)
{
int[] arr={4,7,8,3,9,2};
printArray(arr);//排序前
selectSort(arr);//排序
printArray(arr);//排序后
}
}
2.冒泡排序:BubbleSort,依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
class Test
{
public static void bubbleSort(int[] arr)
{
for(int x=0;x<arr.length-1;x++)//因为是相邻比较,最后一位要减掉.
{
for(int y=0;y<arr.length-x-1;y++)//-x为了每次比较的元素少一个,-1是为了防止越界.
{
if(arr[y]>arr[y+1])//改变成<即是从大到小.
{
arr[y]=arr[y]^arr[y+1];
arr[y+1]=arr[y]^arr[y+1];
arr[y]=arr[y]^arr[y+1];
}
}
}
}
public 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]+"]");
}
}
}
public static void main(String[] args)
{
int[] arr={3,7,5,2,8};
printArray(arr);
bubbleSort(arr);
printArray(arr);
}
}
目前最有效率最快的排序是希尔排序.
如果数组中的数据非常多,用selectsort和bubblesort就比较费时了,因为每次都要换位置,在堆内存中换位置比较耗资源.
在java中java提供了能自动排序的工具,在代码的第一行输入import java.util.Arrays;然后就可以在主函数调用了:
import java.util.Arrays;
class Test
{
public 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]+"]");
}
}
}
public static void main(String[] args)
{
int[] arr={7,4,9,2,5,3};
printArray(arr);
Arrays.sort(arr);//当在第一行输入了import java.util.Arrays;之后就可以在这里直接输入Arrays.sort(arr);来调用了,但默认是升序.
printArray(arr);
}
}
所以如果想要降序,排列,则在输入Arrays.sort(arr)之后,再打印的时候从最后一位开始后打印不就是降序了,比如:
import java.util.Arrays;
class Test
{
public static void printArray(int[] arr)
{
System.out.print("[");
for(int x=arr.length-1;x>=0;x--)//注意这里是从数组的最后一位开始遍历到第一位.
{
if(x!=0)
{
System.out.print(arr[x]+", ");
}
else
{
System.out.println(arr[x]+"]");
}
}
}
public static void main(String[] args)
{
int[] arr={3,7,6,2,9,5};
Arrays.sort(arr);
printArray(arr);
}
}
发现在selectsort和bubblesort都需要进行位置的置换,所以可以把这部分代码单独封装成函数.
class Test
{
public static void main(String[] args)//主函数.
{
int[] arr={7,4,6,9,2,4,1};
printArray(arr);
System.out.println(setMin(arr));
//selectSort(arr);
bubbleSort(arr);
printArray(arr);
}
public static void swap(int[] arr,int x,int y)//置换数组中的两个元素.
{
arr[x]=arr[x]^arr[y];
arr[y]=arr[x]^arr[y];
arr[x]=arr[x]^arr[y];
}
public static int setMin(int[] arr)//求数组中的最小值.
{
int min=0;
for(int x=1;x<arr.length;x++)
{
if(arr[min]>arr[x])
{
swap(arr,min,x);
}
}
return arr[min];
}
//控制打印的顺序也可以控制数组的升降序.
public 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]+"]");
}
}
}
public static void selectSort(int[] arr)//选择排序.升序.
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=x+1;y<arr.length;y++)
{
if(arr[x]>arr[y])//控制升序还是降序.
{
swap(arr,x,y);
}
}
}
}
public static void bubbleSort(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])//控制升降序.
{
swap(arr,y,y+1);
}
}
}
}
}
查找数组中某个元素的角标.
/*
定义功能:查找key第一次出现在数组中的位置,假如有两个相同的key,只会返回第一个key的位置.
*/
class Test
{
public static void main(String[] args)
{
int[] arr={3,6,2,7,5,1,9};
System.out.println(getIndex(arr,10));
}
public static int getIndex(int[] arr,int key)
{
for(int x=0;x<arr.length;x++)
{
if(arr[x]==key)
{
return x;
}
}
return -1;//惯例是当数组中所求元素角标不存在的时候,默认返回-1.
}
}
上面的查找方式是挨个查找,可以用于有序或者无序的数组,但如果元素多就比较费时.对于有序数组可以用折半查找方式,要么数组从小到大,要么从大到小.
折半查找,例一:
class Test
{
public static void main(String[] args)
{
int[] arr={3,5,9,35,67,89,150};
System.out.println(halfSearch(arr,150));
}
public static int halfSearch(int[] arr,int key)
{
int min,max,mid;
min=0;
max=arr.length-1;
mid=(min+max)/2;
while(arr[mid]!=key)
{
if(arr[mid]<key)
{
min=mid+1;
}
else if(arr[mid]>key)
{
max=mid-1;
}
if(min>max)
{
return -1;
}
mid=(min+max)/2;
}
return mid;
}
}
折半查找,例二:
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;
}
else if(key<arr[mid])
{
max=mid-1;
}
else
{
return mid;
}
}
return -1;
}
折半查找扩展,需求:有一个有序的数组,要将一个元素插入到该数组中,并保证该数组还是有序的.先对在数组中查找要插入的那个数是否存在,如果存在,就把这个数放在数组中已有的那个位置上,然后顺延,如果不存在,则不要返回-1,返回min,min就是那个数要插入的角标位置.比如
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])
{
max=mid-1;
}
else if(key>arr[mid])
{
min=mid+1;
}
else
{
return mid;
}
}
return min;
}
public static void main(String[] args)
{
int[] arr={3,5,8,9,34,67,99};
System.out.println(halfSearch_2(arr,37));
}
结果会显示5,那么5就是37所要插入的角标位置.
练习:
1.十进制转二进制:
public static void toBin(int num)
{
while(num>0)
{
System.out.println(num%2);
num=num/2;
}
}
public static void main(String[] args)
{
toBin(6);
}
如果要按顺序显示则可以用一个容器进行存储,再反向打印.
public static void toBin(int num)
{
StringBuffer sb= new StringBuffer();//用于存储数据的容器.
while(num>0)
{
sb.append(num%2);//添加新的数据到这个容器.
num=num/2;
}
System.out.println(sb.reverse());//反向打印.
}
public static void main(String[] args)
{
toBin(6);
}
2.十进制转十六进制:
public static void main(String[] args)
{
tohex(60);
}
public static void toHex(int num)
{
StringBuffer sb=new StringBuffer();
for(int x=0;x<8;x++)//因为一个int含四个八位,也就是八个四位,一个四位代表一个十六进制数,所以最多只能右移八次.
{
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());
}
十进制转十六进制的另一种方法:
/*
十六进制的十六个数刚好对应数组的角标,如果建立一个表,表示十六进制的数和数组角标的对应关系,那么在&15之后的数就不用再减10加'A'了,直接查表就可以知道对应的字母.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*/
public static void main(String[] args)
{
toHex(60);
}
public static void toHex(int num)
{
char[] chs={'0','1','2','3',
'4','5','6','7',
'8','9','A','B',
'C','D','E','F',};
for(int x=0;x<8;x++)
{
int temp=num&15;
System.out.print(chs[temp]);
num=num>>>4;
}
}
但是打印的结果是倒着的,需要用一个像StringBuffer一样的来存储数据,进行反向打印,这里用数组来代替StringBuffer进行存储.
public static void main(String[] args)
{
toHex(60);
}
public static void toHex(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类型的十六进制最多是一个八位,二进制是四个八位.所以这里的容器长度是8.
int pos=arr.length;//定义一个指针.
while(num!=0)
{
int temp=num&15;
arr[--pos]=chs[temp];
num=num>>>4;
}
for(int x=pos;x<arr.length;x++)
{
System.out.print(arr[x]);//如果挨个对arr进行打印,就会打印出空格,这个空格是'\u0000','是字符数组被定义后的初始化值,表示一个空位,相当于一个空格u表示Unicode,
}
}
上面这个代码是通用的,同样可以用于十进制转二进制.
public static void main(String[] args)
{
toBin(60);
}
public static void toBin(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 x=pos;x<arr.length;x++)
{
System.out.print(arr[x]);
}
}
发现在进行十进制转二进制和八进制,十六进制的时候,有共用的代码,所以提取出共用代码之后:
public static void main(String[] args)
{
toBin(60);
toOct(60);
toHex(60);
}
public static void trans(int num,int base,int offset)//进制转换的共用部分.三种转换不同是模以的基数和移位的数.
{
if(num==0)
{
System.out.println(0);
return;
}
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 x=pos;x<arr.length;x++)
{
System.out.print(arr[x]);
}
System.out.println();
}
public static void toBin(int num)//十进制转二进制.
{
trans(num,1,1);
}
public static void toOct(int num)//十进制转八进制.octonary八进制.
{
trans(num,7,3);
}
public static void toHex(int num)//十进制转十六进制.
{
trans(num,15,4);
}
二维数组
格式的第一种写法:
int[][] arr = new int[ 3][ 2];
定义了名称为arr的二维数组;
二维数组中有3个一维数组;
每一个一维数组中有2个元素;
一维数组的名称分别为arr[0], arr[1], arr[2];
给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
格式的第二种写法:
int[][] arr=new int[3][];//可以只定义二维数组中有几个一维数组,但没有定义每个一维数组的长度.
每一个一维数组的初始化值都是null.
可以单独给每一个一维数组定义长度.
public static void main(String[] args)
{
int[][] arr=new int[3][];
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
System.out.println(arr[1]);
}
结果是[I@b5dac4,因为每个一维数组定义了长度,所以结果是一维数组的地址值,而不是null.
给一维数组定义完长度之后,可以打印出一维数组的长度:
system.out.println(arr[0].length);
格式的第三种写法:
int[][] arr={{},{},{}};
另外一维和二维数组还有其他写法,注意空格的位置.需要注意在实际开发中很少会用这么别扭的写法,这个仅作为sun认证的考试题出现.
int[] x;int x[];
int[][] x;int x[][];int[] x[];
例如:
1.
public static void main(String[] args)
{
int[][] arr=new int[3][2];
System.out.println(arr);
}
结果是[[I@b5dac4,表示的是打印的二维数组的地址值,注意开头的两个[[表示是二维数组.
2.
public static void main(String[] args)
{
int[][] arr=new int[3][2];
System.out.println(arr[0]);
}
结果是[I@b5dac4,表示打印的是二维数组的第一个一维数组的地址值,注意开头变成了一个[.
3.
public static void main(String[] args)
{
int[][] arr=new int[3][];
System.out.println(arr[0]);
}
结果是null.因为没有定义每个一维数组的长度,所以结果就是初始化值null.但是如果是指定了长度的数组,那么每个数组的元素初始化值是0.
比如:
public static void main(String[] args)
{
int[] arr=new int[3];
System.out.println(arr[1]);
}
结果是0.
4.需求:已知公司每个部门的销售业绩,求总销售额.
public static void main(String[] args)
{
int[][] arr={{1,4,6,7},{3,5,8,9},{2,5,7,4}};
int sum=0;
for(int x=0;x<arr.length;x++)
{
for(int y=0;y<arr[x].length;y++)
{
sum=sum+arr[x][y];
}
}
System.out.println("sum="+sum);
}
5.下列那个选项是对的
已知int[] x,y[];//其实就是int[] x;int[] y[];所以x是一维数组,y是二维数组.
a.
x[0]=y;//错误,一维数组的一个元素不能等于一个二维数组.
b.
y[0]=x;//正确.
c.
y[0][0]=x;//错误.
d.
x[0][0]=y;//错误
e.
y[0][0]=x[0];//正确
f.
x=y;//错误
---------------------- android培训、java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima