1 数组的定义与使用
所谓的数组指的是一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作,数组属于引用数据类型,所以这里面又会牵扯到内存分配。
数组的定义语法有如下两类:
声明并开辟数组:数据类型 []数组名称=new 数据类型[长度];或者:数据类型 数组名称[]=new 数据类型[长度];
分步进行数组空间开辟:①声明数组:数据类型 []数组名称=null;或者 数据类型 数组名称[]=null;
②开辟数组空间:数组名称=new 数据类型[长度];
示例:一个简单的数组实例
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[3];
data[0]=12;
data[1]=13;
data[2]=45;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
12
13
45
示例:采用分步模式开辟数组空间
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=null;
data=new int[3];
data[0]=12;
data[1]=13;
data[2]=45;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果同上。
注意:数组属于引用类型,所以在数组使用之前一定要开辟空间(实例化)。
(2)数组的引用分析
既然数组本身也属于引用数据类型,那么也一定可以发生引用传递。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[3];
int temp[]=null;//声明对象
data[0]=12;
data[1]=13;
data[2]=45;
//进行引用传递,不要出现[]
temp=data;//也可以直接写成int temp[]=data;这里的data传递的是地址,也就是使得temp指向的内容和data指向的是同一个。
temp[0]=66;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
66
13
45
(3)数组的静态初始化
静态初始化的方法:①简化格式:数据类型 数组名称[]={值...}
②完整格式:数据类型 数组名称[]=new 数据类型[]{值...}
示例:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[]{12,3,2,34,4,30,3,35};
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
12
3
2
34
4
30
3
35
(4)数组与方法调用
数组是一个引用数据类型,可以为其设置多个栈内存指向,所以在进行数组操作的时候也可以将其通过方法进行处理。
示例:方法接受数组
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[]{1,2,3,4,5};
printArray(data);//这不就相当于int temp[]=data;
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:1 2 3 4 5
示例:方法返回数组
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=init();
printArray(data);//这不就相当于int temp[]=data;
}
public static int [] init()
{
return new int[]{1,2,3,4,5};
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:1 2 3 4 5
示例:将数组中的内容乘以2倍
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=init();
inc(data);//将数组中的内容乘以2倍
printArray(data);//这不就相当于int temp[]=data;
}
public static void inc(int arr[])
{
for(int x=0;x<arr.length;x++)
{
arr[x]*=2;
}
}
public static int [] init()
{
return new int[]{1,2,3,4,5};
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:2 4 6 8 10
如下图分析:
(5)
(6)数组拷贝:指的是将一个数组的部分内容替换掉另外一个数组的部分内容。
方法(加工过的):System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝长度);
示例:实现数组拷贝
源数组A;1,2,3,4,5,6,7,8,9;
源数组B:11,22,33,44,55,66,77,88,99;
替换后的源数组A:1,,55,66,77,5,6,7,8,9;
public class Test {
public static void main(String[] args) {
int dataA[]=new int[] {1,2,3,4,5,6,7,8,9};
int dataB[]=new int[] {11,22,33,44,55,66,77,88,99};
System.arraycopy(dataB,4,dataA,1,3);
printArray(dataA);
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
System.out.println();
}
}
(7)数组实例:数组数据统计
现在假设给您一个数组,要求可以统计出该数组的最大值,最小值,平均值以及综和。这种操作肯定通过循环来完成。
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,66,5,6,7,8,9};
int max=data[0];//假设第一个数据为当前最大数
int min=data[0];//假设第一个数据为当前最小数据
int sum=data[0];//从第一个开始累加
for(int x=1;x<data.length;x++)
{
sum+=data[x];
if(data[x]>max)
{
max=data[x];
}
if(min>data[x])
{
min=data[x];
}
}
System.out.println("最大"+max);
System.out.println("最小"+min);
System.out.println("总和"+sum);
System.out.println("平均值"+sum/(double)data.length);
}
}
结果:
最大66
最小1
总和111
平均值11.1
注意:现在的主方法中代码有点多,所以改正如下
示例:
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,66,5,6,7,8,9};
double result[]=stat(data);//数据统计
System.out.println("最大"+ result[0]);
System.out.println("最小"+ result[1]);
System.out.println("总和"+ result[2]);
System.out.println("平均值"+ result[3]);
}
//此时需要返回的数据一共有四个,一个方法只能返回一种数据类型,那么此时只能用数组
//数组【0】表示最大值,数组【1】表示最小值,数组【2】表示总和,数组【3】表示平均值
public static double[] stat(int data[])
{
double retData[]=new double[4];
retData[0]=data[0];//假设第一个数据为当前最大数,赋值给retData[1]
retData[1]=data[0];//假设第一个数据为当前最小数
retData[2]=data[0];//从第一个开始累加,将第一个数据赋值给retData【2】
for(int x=1;x<data.length;x++)
{
retData[2]+=data[x];
if(data[x]>retData[0])
{
retData[0]=data[x];
}
if(retData[1]>data[x])
{
retData[1]=data[x];
}
}
retData[3]=retData[2]/data.length;
return retData;
}
}
结果:
最大66.0
最小1.0
总和111.0
平均值11.1
(8)数组排序
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,69,3,4,6,5,23,7,8,9};
sort(data);
printArray(data);
}
public static void sort(int arr[])
{
//因为冒泡排序次数为n*(n-1)次。
for(int x=0;x<arr.length-1;x++)
{
//因为排除一个最大值后,它后面的值就不用再看了,所以减去x
for(int y=0;y<arr.length-1-x;y++)
{
if(arr[y]>arr[y+1])
{
int temp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+",");
}
}
}
结果:1,3,4,5,6,7,8,9,23,69,
(9)数组转置
最简单的理解就是收尾交换。有两种思路:
思路一:开辟一个新的等长数组,将原始数组倒序放入(最好不用)
思路二:在此数组中进行转换(只需将数组长度除以2即可)
示例:
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,5,6,7,8};
reverse(data);//反转
printArray(data);
}
public static void reverse(int arr[])
{
int center=arr.length/2;//转换次数
int head=0;//头部开始索引
int tail=arr.length-1;//尾部开始索引
for(int x=0;x<center;x++)
{
int temp=arr[head];
arr[head]=arr[tail];
arr[tail]=temp;
head++;
tail--;
}
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+",");
}
}
}
结果:8,7,6,5,4,3,2,1,
(10)二分查找(折半查找)
如果要求你在一个指定的数组之中查询一个数据的位置
示例:实现二分查找(用递归操作完成)
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,5,6,7,8};
int search=5;
System.out.println(binarySearch(data,0,data.length-1,search));
}
//from是从什么地方开始找,to是找到哪里为止,找的值是key
public static int binarySearch(int arr[],int from,int to,int key)
{
if(from<to)
{
int mid=(from/2)+(to/2);//确定中间点
if(arr[mid]==key)
{
return mid;//取得当前索引
}else if(arr[mid]<key)
{
return binarySearch(arr,from+1,to,key);
}else if(arr[mid]>key)
{
return binarySearch(arr,from,mid-1,key);
}
}
return -1;
}
}
结果:4
(11)对象数组(核心)
对象数组往往是以引用数据类型数据为主的定义,如:类,接口
示例:对象数组的动态初始化
public class Test {
public static void main(String[] args) {
Person per[]=new Person[3] ;
per[0]=new Person("张三",12);
per[1]=new Person("李四",52);
per[2]=new Person("王五",22);
for(int x=0;x<per.length;x++)
{
System.out.println(per[x].getInfo());
}
}
}
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getInfo()
{
return "name="+this.name+",age="+this.age;
}
}
结果:
name=张三,age=12
name=李四,age=52
name=王五,age=22
示例:对象数组的静态初始化
public class Test {
public static void main(String[] args) {
Person per[]=new Person[] {
new Person("张三",12),
new Person("李四",52),
new Person("王五",22)
} ;
for(int x=0;x<per.length;x++)
{
System.out.println(per[x].getInfo());
}
}
}
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getInfo()
{
return "name="+this.name+",age="+this.age;
}
}
结果:
name=张三,age=12
name=李四,age=52
name=王五,age=22
所谓的数组指的是一组相关类型的变量集合,并且这些变量可以按照统一的方式进行操作,数组属于引用数据类型,所以这里面又会牵扯到内存分配。
数组的定义语法有如下两类:
声明并开辟数组:数据类型 []数组名称=new 数据类型[长度];或者:数据类型 数组名称[]=new 数据类型[长度];
分步进行数组空间开辟:①声明数组:数据类型 []数组名称=null;或者 数据类型 数组名称[]=null;
②开辟数组空间:数组名称=new 数据类型[长度];
示例:一个简单的数组实例
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[3];
data[0]=12;
data[1]=13;
data[2]=45;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
12
13
45
示例:采用分步模式开辟数组空间
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=null;
data=new int[3];
data[0]=12;
data[1]=13;
data[2]=45;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果同上。
注意:数组属于引用类型,所以在数组使用之前一定要开辟空间(实例化)。
(2)数组的引用分析
既然数组本身也属于引用数据类型,那么也一定可以发生引用传递。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[3];
int temp[]=null;//声明对象
data[0]=12;
data[1]=13;
data[2]=45;
//进行引用传递,不要出现[]
temp=data;//也可以直接写成int temp[]=data;这里的data传递的是地址,也就是使得temp指向的内容和data指向的是同一个。
temp[0]=66;
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
66
13
45
(3)数组的静态初始化
静态初始化的方法:①简化格式:数据类型 数组名称[]={值...}
②完整格式:数据类型 数组名称[]=new 数据类型[]{值...}
示例:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[]{12,3,2,34,4,30,3,35};
for(int x=0;x<data.length;x++)
{
System.out.println(data[x]);
}
}
}
结果:
12
3
2
34
4
30
3
35
(4)数组与方法调用
数组是一个引用数据类型,可以为其设置多个栈内存指向,所以在进行数组操作的时候也可以将其通过方法进行处理。
示例:方法接受数组
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=new int[]{1,2,3,4,5};
printArray(data);//这不就相当于int temp[]=data;
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:1 2 3 4 5
示例:方法返回数组
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=init();
printArray(data);//这不就相当于int temp[]=data;
}
public static int [] init()
{
return new int[]{1,2,3,4,5};
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:1 2 3 4 5
示例:将数组中的内容乘以2倍
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int data[]=init();
inc(data);//将数组中的内容乘以2倍
printArray(data);//这不就相当于int temp[]=data;
}
public static void inc(int arr[])
{
for(int x=0;x<arr.length;x++)
{
arr[x]*=2;
}
}
public static int [] init()
{
return new int[]{1,2,3,4,5};
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
}
}
结果:2 4 6 8 10
如下图分析:
(5)
(6)数组拷贝:指的是将一个数组的部分内容替换掉另外一个数组的部分内容。
方法(加工过的):System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝长度);
示例:实现数组拷贝
源数组A;1,2,3,4,5,6,7,8,9;
源数组B:11,22,33,44,55,66,77,88,99;
替换后的源数组A:1,,55,66,77,5,6,7,8,9;
public class Test {
public static void main(String[] args) {
int dataA[]=new int[] {1,2,3,4,5,6,7,8,9};
int dataB[]=new int[] {11,22,33,44,55,66,77,88,99};
System.arraycopy(dataB,4,dataA,1,3);
printArray(dataA);
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+" ");
}
System.out.println();
}
}
(7)数组实例:数组数据统计
现在假设给您一个数组,要求可以统计出该数组的最大值,最小值,平均值以及综和。这种操作肯定通过循环来完成。
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,66,5,6,7,8,9};
int max=data[0];//假设第一个数据为当前最大数
int min=data[0];//假设第一个数据为当前最小数据
int sum=data[0];//从第一个开始累加
for(int x=1;x<data.length;x++)
{
sum+=data[x];
if(data[x]>max)
{
max=data[x];
}
if(min>data[x])
{
min=data[x];
}
}
System.out.println("最大"+max);
System.out.println("最小"+min);
System.out.println("总和"+sum);
System.out.println("平均值"+sum/(double)data.length);
}
}
结果:
最大66
最小1
总和111
平均值11.1
注意:现在的主方法中代码有点多,所以改正如下
示例:
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,66,5,6,7,8,9};
double result[]=stat(data);//数据统计
System.out.println("最大"+ result[0]);
System.out.println("最小"+ result[1]);
System.out.println("总和"+ result[2]);
System.out.println("平均值"+ result[3]);
}
//此时需要返回的数据一共有四个,一个方法只能返回一种数据类型,那么此时只能用数组
//数组【0】表示最大值,数组【1】表示最小值,数组【2】表示总和,数组【3】表示平均值
public static double[] stat(int data[])
{
double retData[]=new double[4];
retData[0]=data[0];//假设第一个数据为当前最大数,赋值给retData[1]
retData[1]=data[0];//假设第一个数据为当前最小数
retData[2]=data[0];//从第一个开始累加,将第一个数据赋值给retData【2】
for(int x=1;x<data.length;x++)
{
retData[2]+=data[x];
if(data[x]>retData[0])
{
retData[0]=data[x];
}
if(retData[1]>data[x])
{
retData[1]=data[x];
}
}
retData[3]=retData[2]/data.length;
return retData;
}
}
结果:
最大66.0
最小1.0
总和111.0
平均值11.1
(8)数组排序
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,69,3,4,6,5,23,7,8,9};
sort(data);
printArray(data);
}
public static void sort(int arr[])
{
//因为冒泡排序次数为n*(n-1)次。
for(int x=0;x<arr.length-1;x++)
{
//因为排除一个最大值后,它后面的值就不用再看了,所以减去x
for(int y=0;y<arr.length-1-x;y++)
{
if(arr[y]>arr[y+1])
{
int temp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+",");
}
}
}
结果:1,3,4,5,6,7,8,9,23,69,
(9)数组转置
最简单的理解就是收尾交换。有两种思路:
思路一:开辟一个新的等长数组,将原始数组倒序放入(最好不用)
思路二:在此数组中进行转换(只需将数组长度除以2即可)
示例:
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,5,6,7,8};
reverse(data);//反转
printArray(data);
}
public static void reverse(int arr[])
{
int center=arr.length/2;//转换次数
int head=0;//头部开始索引
int tail=arr.length-1;//尾部开始索引
for(int x=0;x<center;x++)
{
int temp=arr[head];
arr[head]=arr[tail];
arr[tail]=temp;
head++;
tail--;
}
}
public static void printArray(int temp[])
{
for(int x=0;x<temp.length;x++)
{
System.out.print(temp[x]+",");
}
}
}
结果:8,7,6,5,4,3,2,1,
(10)二分查找(折半查找)
如果要求你在一个指定的数组之中查询一个数据的位置
示例:实现二分查找(用递归操作完成)
public class Test {
public static void main(String[] args) {
int data[]=new int[] {1,2,3,4,5,6,7,8};
int search=5;
System.out.println(binarySearch(data,0,data.length-1,search));
}
//from是从什么地方开始找,to是找到哪里为止,找的值是key
public static int binarySearch(int arr[],int from,int to,int key)
{
if(from<to)
{
int mid=(from/2)+(to/2);//确定中间点
if(arr[mid]==key)
{
return mid;//取得当前索引
}else if(arr[mid]<key)
{
return binarySearch(arr,from+1,to,key);
}else if(arr[mid]>key)
{
return binarySearch(arr,from,mid-1,key);
}
}
return -1;
}
}
结果:4
(11)对象数组(核心)
对象数组往往是以引用数据类型数据为主的定义,如:类,接口
示例:对象数组的动态初始化
public class Test {
public static void main(String[] args) {
Person per[]=new Person[3] ;
per[0]=new Person("张三",12);
per[1]=new Person("李四",52);
per[2]=new Person("王五",22);
for(int x=0;x<per.length;x++)
{
System.out.println(per[x].getInfo());
}
}
}
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getInfo()
{
return "name="+this.name+",age="+this.age;
}
}
结果:
name=张三,age=12
name=李四,age=52
name=王五,age=22
示例:对象数组的静态初始化
public class Test {
public static void main(String[] args) {
Person per[]=new Person[] {
new Person("张三",12),
new Person("李四",52),
new Person("王五",22)
} ;
for(int x=0;x<per.length;x++)
{
System.out.println(per[x].getInfo());
}
}
}
class Person
{
private String name;
private int age;
public Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getInfo()
{
return "name="+this.name+",age="+this.age;
}
}
结果:
name=张三,age=12
name=李四,age=52
name=王五,age=22