一、数组
- 概念:数组是一种容器,可以同时存放多个同型数据
- 特点:
数组是一种引用数据类型
数组当中的多个数据,其数据类型必须统一
数组的长度在程序运行期间不能改变 - 数组的初始化:在内存当中创建一个数组,并向其中赋予一些默认值
- 两种常见的初始化方式:
- 动态初始化(指定数组长度)
/**
*动态初始化格式:
*数据类型[] 数组名称 = new 数据类型[数组长度]
*/
//创建一个数组,里面能放300个int类型的数据
int[] arrayA = new int[300];
//创建一个数组,里面能放10个double类型的数据
double[] arrayB = new double[10];
//创建一个数组,里面能放5个字符串
String[] arrayC = new String[5];
- 静态初始化(指定数组内容)
- 虽然静态初始化没有指定数组的长度,但是根据赋予的内容也能够自动推算出数组的长度
- 静态初始化有标准格式和省略格式两种
/**
*静态初始化标准格式:
*数据类型[] 数组名称 = new 数据类型[]{元素1,元素2,····元素n};
*/
//创建一个数组,里面存放int类型的5、15、25
int[] arrayA = new int[]{5,15,25};
//创建一个数组,里面存放字符串:"Hello"、"World"、"Java"
String[] arrayB = new String[]{"Hello","World","Java"};
/**
*静态初始化省略格式:
*数据类型[] 数组名称 = {元素1,元素2,······元素n};
*/
int[] arrayA = {1314,520};
- 数组的初始化可以分为两个步骤:
注:静态初始化的省略格式不能拆分成两个部分
int[] arrayA;
arrayA = new int[520];
int[] arrayB;
arrayB = new int[]{1314,520};
- 使用建议:
- 如果不确定数组的内容,就用动态初始化
- 若明确数组中的内容,则使用静态初始化
int[ ]:int类型的的数组
double[ ]:double类型的数组
char[ ] :char类型的数组
String[ ]: String 类型的数组
二、获取数组中的元素并赋值
- 访问数组元素的格式:
(1)数组名称 [ 索引值 ]
(2)将数组中的元素赋给一个变量,然后打印出这个变量值 - 索引值:是一个int数字,代表数组当中的元素编号。索引值从0开始,至数组长度-1为止
- 使用动态初始化数组时,其中的元素将会自动拥有一个默认值。静态初始化其实也有默认值,只不过系统马上自动将默认值替换成了大括号中我们赋予的具体数值
- 若数组没有初始化,数组元素有默认值
- [整数类型 ] :默认为0
- [浮点数类型]:默认为0.0
- [字符类型]:默认为’/u0000’
- [布尔类型]:默认为false
- [引用类型]:默认为null
- 赋值:形如array[1]=1314;
int[] array = new int[]{10,20,30};
//将打印10
System.out.println(array[0]);
int number = array[1];
//将打印20
System.out.println(number);
三、Java中的内存划分
Java程序的内存需要划分为5个部分
- 栈(Stack):存放的都是方法中的局部变量(方法中的参数或者是方法{ }内部的变量)。方法的运行一定要在栈当中。(进栈运行)
特点:变量有作用域,一旦超出作用域范围,立刻从栈内存中消失 - 堆(Heap):凡是new出来的东西,都在堆当中。堆内存里面的东西都有一个16进制地址值。
堆内存里面的数据都有默认值,规则:
如果是整数,默认为0
如果是浮点型:默认为0.0
如果是字符,默认为’\u0000’
如果是布尔,默认为false
如果是引用类型,默认为null - 方法区(Method Area):存储.class相关信息,包含方法的信息。但是要想执行,需要把信息加载到栈当中,并为其开辟一块内存空间,即所谓的”进栈执行“
- 本地方法栈(Native Method Stack):与操作系统相关
- 寄存器(pc Register):与CPU相关
四、一个数组的内存图
五、两个数组的内存图
六、两个引用指向同一个数组的内存图
七、数组常见问题
- ArrayIndexOutOfBoundsException:数组索引越界异常
- 如果访问数组元素的时候,索引编号并不存在,那么将会发生数组索引越界异常
- 解决方法:把越界的变成不越界的就OK了
- NullPointerException:空指针异常
- 数组必须进行new初始化才能使用其中的元素,如果只是赋值了一个null,没有进行new创建,那么将会发生空指针异常
- 解决方法:补上new
八、获取数组的长度
- 格式:
数组名称.length
这将会得到一个int类型的数字,代表数组的长度
public static void main(String[] args){
/**
*动态数组
*/
int[] arrayA = new int[3];
/**
*静态数组
*/
int[] arrayB = {1,2,3,4,5,6,7,8,9,10,11};
/**
*arrayA.length获取数组arrayA的长度
*/
int len = arrayA.length;
/**
*打印3
*/
System.out.println("数组arrayA的长度是:"+len);
/**
*打印11
*/
System.out.println("数组arrayB的长度是:"+arrayB.length);
}
- 数组的长度在程序运行时不能改变
/**
*注意:arrayC只是一个变量名,new后面的才是数组,即int[3]、int[5]才是真正的数组,而且它们是两个不同的数组
*/
int[] arrayC = new int[3];
/**
*输出的长度是3
*/
System.out.println("长度是:"+arrayC.length);
arrayC = new int[5];
/**
*输出的长度是5
*/
System.out.println("长度是:"+arrayC.length);
九、遍历数组
- 定义:对数组当中的元素进行逐一、挨个的处理。默认的处理方式就是打印输出
示例:
public static void main(String[] args) {
int[] array = new int[] {11,12,34,56,78,89};
for(int i = 0; i< array.length; i++)
{
System.out.println("第"+(i+1)+"个数是:"+array[i]);
}
}
例题1:求出数组中的最大值
public static void main(String[] args) {
int[] array = new int[] { 5, 15, 20, 10, 10000,20,24};
int max = array[0];
for(int i = 1; i<array.length;i++){
max = max>array[i]?max:array[i];
}
System.out.println(max);
}
例2. 数组元素的反转(不能使用新数组)
分析:
public static void main(String[] args) {
int[] array = new int[] {10, 20,30,40,50};
for(int i = 0; i<array.length; i++){
System.out.println(array[i]);
}
/**
*对数组元素进行反转。其实,反转就是对称位置的元素交换位置
*/
for(int min = 0,max = array.length-1; min < max; min++, max--){
int temp = array[min];
array[min] = array[max];
array[max] = temp;
}
/**
*打印出反转后的数组元素
*/
for(int i = 0; i<array.length;i++)
{
System.out.println(array[i]);
}
}
十、数组做参数传递地址
示例:定义一个方法,用于打印数组元素反转后的结果
分析:
三要素:
返回值类型:只是进行打印而已,不需要进行计算,也没有结果,所以用void
方法名称:printArray
参数列表:必须给我数组,我才能打印其中的元素。int[ ] array
public static void main(String[] args) {
int[] array = new int[] {10, 20,30,40,50};
System.out.println(array); //地址值
/**
*调用方法
*/
printarrAy(array); //传递进去的就是array当中保存的地址值
}
public static void printArray(int[] array){
System.out.println("printArayy方法受到的参数是:");
System.out.println(array); //地址值
for(int i = 0; i<array.length; i++){
System.out.println(array[i]);
}
for(int min = 0,max = array.length-1; min < max; min++, max--){
int temp = array[min];
array[min] = array[max];
array[max] = temp;
}
for(int i = 0; i<array.length;i++)
{
System.out.println(array[i]);
}
}
反思:数组可以作为方法的参数,当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值
十一、数组作为方法的返回值——返回地址
- 一个方法可以有0个、1个或者多个参数,但是只能有0个或者1个返回值,不能有多个返回值。如果希望一个方法当中产生多个结果数据进行返回,怎么办?
解决方案:使用一个数组作为返回值类型即可
public static void main(String[] args) {
int[] result = calculate(10, 20, 30);
System.out.println("main方法接受到的返回值数组是:"+ result); //地址值,并根据这个地址值访问sum和avg
System.out.println("总和"+result[0]);
System.out.println("平均数"+result[1]);
}
public static int[] calculate(int a, int b, int c){
int sum = a + b + c; //总和
int avg = sum/3; //平均数
/**
* 如果两个结果都希望进行返回
*/
/**
*写法一:
*int[] array = new int[2];
*array[0] = sum;//总和
*array[1] = avg;//平均数
*/
int[] array = {sum , avg};
System.out.println("calculate方法内部数组是:"+array); //地址值
return array;
}
总结:任何数据类型都能作为方法的参数类型或者返回值类型
- 数组作为方法的参数,传递进去的其实是数组的地址值
- 数组作为方法的返回值,返回的其实也是数组的地址值