------<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
A、基本概念
定义:同一个类型数据的集合,其实数组就是一个容器。
数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
格式1:
元素类型[ ] 数组名= new 元素类型[ 元素个数或数组长度]
示例:int [ ]arr = new int[3 ]也可以写成:int arr [] = new int[3 ],但一般都按规范来写。
定义一个可以存储3个整数的容器。
int [ ]x = new int[ 3 ];
格式2:
元素类型[ ] 数组名=new 元素类型[ ] { 元素,元素,……};
示例: int [ ] arr = new int[ ] {3,5,1,7 };
也可简化为:int [ ]arr = { 3,5,1,7 };
B、内存结构
前言:java程序在运行时,需要在内存中分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据的方式和内存管理方式。
栈内存:用于存储局部变量,当数据使用完毕后,所占的空间会被自动释放。
堆内存:
*数组和对象,通过new建立的实例都存放在堆内存中。
*每一个实体都有内存地址值
*实体中的变量都有默认的初始化值(例int:0;boolean:false;double:0.0)
*实体不在被使用,会在不确定的使劲按内被垃圾回收器回收
另:除了以上两个内存区外,还有方法区、本地方法区、寄存器
实例:
classArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
arr=null;
System.out.println(arr[3]);
}
}
在没有arr=null;运行时给出错误提示:
Array indexout of bounds exception:3:操作数组时,访问到了数组中不存在的角标。
在有arr=null;运行时给出错误提示:
Null pointerexception:空指针异常,当引用没有任何指向值为null的情况,该引用还在用语操作实体。
C 1、数组的常见操作——遍历
获取数组中的元素,通常会用到遍历
classArrayDemo2
{
public static void main(String[] args)
for(int x=0; x<arr.length; x++)
{
int[] arr = new int[]{ 3,6,5,1,8,9,67};
System.out.println(“arr[“+x+”]=”+arr[x]+”;”);
}
}
总结:数组中有一个属性可以直接获取到数组元素的个数:length
使用方式:”数组名称.length”
上面的程序在或许打印元素的取值范围时就有用到。
练习:用于打印数组中的元素int[]arr={ 3,6,5,1,8,9,67};,元素间用逗号隔开
classArrayDemo2
{
public static void main(String[] args)
{
int[]arr={ 3,6,5,1,8,9,67}
printArray(arr);
}
public static void printArray([ ]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.print(arr)”来进行打印,那么得到的会是该数组空间的16进制的内存地址值。
练习题:
给定一个数组{5,1,6,4,2,8,9}
1、 获取该数组中的最大值和最小值。
思路:
a、获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定,通过一个变量进行临时存储。
b、让数组中的每一个元素都和这个变量中的值进行比较,如果大于了变量中的值,就用该变量记录较大值。
c、当所有的元素都比较完成,那么该变量中储存的值就是数组中的最大值了
步骤:
a、 定义变量,初始化数组中的任意一个元素即可,
b、 通过循环语句对数组进行遍历
c、 在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量:
需要定义一个功能来完成,以便提高复用性。
a、 明确结果,数组中的最大元素 int类型
b、 未知内容:一个数组,int[ ]
publicstatic int getMax(int[ ] arr)
{
int max=arr[ 0 ];
for(intx=1;x<arr.length;x++)
{
if(arr[x]>max)
max = arr[ x ];
}
returnmax;
}
publicstatic void main(String[ ] args)
{
int[ ] arr={5,1,6,4,2,8,9}};
int max = getMax(arr);
System.out.println(“max=”+max);
}
获取最大值的另外一种方式。
可不可以将临时变量max初始化为0呢?可以,这种方式,其实是在初始化为数组中任意一个角标。
及:
publicstatic int getMax(int[ ] arr)
{
int max= 0;
for(int x=1;x<arr.length;x++)
{
if(arr[x]>arr[max])
max = x ;
}
returnarr [max] ;
}
publicstatic void main(String[ ] args)
{
int[ ] arr={5,1,6,4,2,8,9}};
int max = getMax(arr);
System.out.println(“max=”+max);
}
获取最小值:(同理)
publicstatic int getMin(int[ ] arr)
{
int min =0
for(int x=1;x<arr.length;x++)
{
if(arr[x]<arr[min])
min=x;
}
returnarr[min];
}
publicstatic void main(String[ ] args)
{
int[ ] arr={5,1,6,4,2,8,9}};
int max = getMax(arr);
int min = getMin(arr)
System.out.println(“max=”+max);
System.out.println(“min=”+min);
}
C2、数组的常见操作——排序
Array.sort(arr); ——java中已经定义好的一种排序方式,开发中,对数组排序,要使用该句代码!
a、选择排序
实例:对数组{5,1,6,4,2,8,9}进行排序。
class ArrayTest1
{
publicstatic void selectsort (int[] arr)
{
for(int x=0; x<arr.length-1; x++)
{
for(inty=x+1; y<arr.length; y++)
{
if(arr[x]>arr[y])
{
inttemp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
}
publicstatic void main(String[] args)
{
int[]arr={5,1,6,4,2,8,9};
printArray(arr);
selectsort(arr);
printArray(arr);
}
publicstatic void printArray(int[]arr)
{
System.out.print("[");
for(intx=0;x<arr.length;x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
}
总结:内循环结束一次,最值出现在头角标位置上
b、冒泡排序
定义:相邻的两个元素进行比较,如果符合条件,换位。
特点:第一圈排序后,最值出现了最后位。
class BubbleSort
{
publicstatic 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])
{
inttemp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
publicstatic void printArray(int[]arr)
{
System.out.print("[");
for(intx=0;x<arr.length;x++)
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.println(arr[x]+"]");
}
}
publicstatic void main(String[] args)
{
int[]arr={5,1,6,4,2,8,9};
printArray(arr);
bubbleSort(arr);
printArray(arr);
}
}
c、排序——换位置功能的提取
引言:发现无论是什么排序,都需要对满足条件的元素进行位置的置换,所以可以把这部分相同的代码提取出来,单独封装成为一个函数!
public static void swap(int[] arr,int a,int b)
{
inttemp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
在上面b中的程序中,可以直接运行swap(arr);
D、数组——查找
定义功能,获取key第一次出现在数组中的位置,如果返回是 -1,那么代表该key值在数组中不存在
实例:
class Index
{
publicstatic void main(String[] args)
{
int[]arr={3,1,5,4,2,9};
intindex=getIndex(arr,2);
System.out.println("index="+index);
}
publicstatic int getIndex(int[]arr,int key)
{
for(int x=0;x<arr.length;x++)
{
if(arr[x]==key)
{
returnx;
}
}
return-1;
}
}
所以,如果在上面的程序的arr数组中出现了两个2,那么index输出的将是第一次2出现的角标值
折半查找
可以提高效率,但是必须要保证该数组是有序的数组。
classHalfSearch
{
public static int halfSearch(int[] arr,intkey)
{
int min,mid,max;
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;
}
public static void main(String[] args)
{
int[] arr={2,4,5,7,19,32,45};
int index=halfSearch(arr,55);
System.out.println("index="+index);
}
}
折半的第二种方式:
classHalfSearch2
{
public static int halfSearch_2(int[]arr,intkey)
{
int min =0,max=arr.length-1,mid;
while (min<=max)
{
mid=(min+max)>>1;//等价于mid=(max+min)/2
if (key>arr[mid])
min=mid+1;
else if (key<arr[mid])
max=mid-1;
else
return mid;
}
return -1;
}
public static void main(String[] args)
{
int[] arr={2,4,5,7,19,32,45};
int index=halfSearch_2(arr,55);
System.out.println("index="+index);
}
}
练习题1:有一个有序的数组,想要将一个元素插入到该数组中,还要保证数组是有序的,如何获取该元素在数组中的位置 {2,4,5,7,19,32,45}
classHalfPractice
{
publicstatic 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 min;
}
public static void main(String[] args)
{
int[] arr={2,4,5,7,19,32,45};
int index=halfSearch_2(arr,8);
System.out.println("index="+index);
}
}
就是在最后返回时将halfSearch2中的return-1改成了return min,此时的min就是8应该所在的位置!
练习题2:十进制转二进制
classArrayTests
{
public static void tobin(int num)
{
while (num>0)
{
System.out.print(num%2);
num=num/2;
}
}
public static void main(String[] args)
{
tobin(6);
}
}
最后的输出结果是011,将显示的结果反过来就是110就是6的2进制数!
练习题3:十进制转十六进制
class ArrayTest16
{
public static void toHex(int num)
{
for (int x=0;x<8 ;x++ )
{
int temp=num&15;
if (temp>9)
System.out.println((char)(temp-10+'A'));
else
System.out.println(temp);
num= num>>> 4;
}
}
public static void main(String[] args)
{
toHex(60);
}
}
查表法:十进制转十六进制
将所有的元素临时存储起来,建立对应关系,每一次&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——角标
classChecktoHex
{
public static void main(String[] args)
{
toHex(60);
}
publicstatic 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.println(chs[temp]);
num=num>>>4;
}
}
发现终于出结果了,但是结果是反着的,想要正过来,可以通过StringBufferreverse功能来完成,但是这个工具还没有学习,所以可以使用已经学过的容器,数组来完成反转存储
classChecktoHex
{
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 pos=arr.length;
while (num!=0)
{
int temp=num & 15;
arr[--pos] = chs[temp];
num = num >>> 4;
}
System.out.println("pos="+pos);
for (int x=pos;x<arr.length ;x++)
{
System.out.print(arr[x]+",");
}
}
public static void main(String[] args)
{
toHex(60);
}
}
同理:编写十转二的查表法程序
class ChecktoBin
{
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;
}
//System.out.println("pos="+pos);
for (int x=pos;x<arr.length ;x++)
{
System.out.print(arr[x]+",");
}
}
public static void main(String[] args)
{
toBin(-6);
}
}
由于通过查表法转二进制和十六进制有很多的相似之处,所以,我们可以从里面提取出一些共同的部分定义其功能!
classTranslation
{
if(num==0)
{
System.out.println(0);
return;
}
public static void main(String[] args)
{
toOct(32);
}
public static void toBin(int num)
{
trans(num,1,1);
}
public static void toOct(int num)
{
trans(num,7,3);
}
public static void toHex(int num)
{
trans(num,15,4);
}
public static void trans(int num,int base,intoffset)
{
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]);
}
}
}
F、数组中的数组
——二维数组
格式1:int[ ] [ ] arr = new int[3][2];
l 定义了名称为arr的二维数组
l 二维数组中有3个一维数组
l 每一个以为数组中有两个元素
l 一维数组的名称分别为arr[0],arr[1], arr[2]
l 给第一个一维数组中角标为1的位赋值78,写法是:arr[0][1]=78;
格式2:int[ ] [ ] arr = new int[3][ ];
l 二维数组中都是3个一维数组
l 每个一维数组都是默认初始化值null
l 可以对这三个一维数组分别进行初始化
l int[ ] [] arr = new int[3][ ];
arr[0]=new int[3];
arr[1]=new int[1];
arr[2]=new int[2];
System.out.println(arr.length);//打印的是二维数组的长度
System.out.println(arr.length);//打印的是二维数组中第一个一维数组的长度
格式3:int[][]arr={{3,5,1,7},{2,3,5,7},{6,1,8,2}}
理解应用,如果上面数组表示一个公司三个销售团队每个季度的销售额度,那么求该公司一年的总销售额度?
分析:把所有的数都要加一边,所以要遍历,先遍历二维数组,再遍历二维数组中一维数组的每一个元素,所以有:
class PlanarArray
{
publicstatic void main(String[] args)
{
int[][]arr={{3,5,1,7},{2,3,5,7},{6,1,8,2}};
intsum=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);
}
}
补充知识:
一维数组的表现形式:
int[] x; int x[];————两种
int[][]y; int[] y[]; int y[][];————三种
练习:给出数组int[]x,y[];请问下面那一个是正确的?
分析:
int[] 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
Summary: []定义在类型当中[]是跟着类型走的,在类型当中[]对他们都有效,而[]跟着字母走那么只对单个字母有效!