04数组和方法
案例分析
现在需要统计某公司员工的工资情况,例如计算平均工资、找到最高工资等。假设该公司有50名员工,用前面所学的知识,程序首先需要声明50个变量来分别记住每位员工的工资,然后在进行操作,这样做会显得很麻烦,而且错误率也会很高。因此我们可以使用容器进行操作。将所有的数据全部存储到一个容器中,统一操作。
容器: 是将多个数据存储到一起,每个数据称为该容器的元素。
生活中的容器: 水杯,衣柜,教室
数组概念: 数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。
数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
float[] a={1.0f,2.0f,3.0f,4.0f,5.0f}
用来存放同一种数据类型的集合,存到数组中的每个数据称为元素,他们都有下标从0开始,我们可以通过下标操作对应的元素
数组常见的概念:数组名、下标(索引)、元素、数组的长度;
数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
l 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是
这块连续空间的首地址。
l 数组的长度一旦确定,就不能修改。
l 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
l 数组的分类:
Ø 按照维度:一维数组、二维数组、三维数组、…
Ø 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象和数组)
一维数组的声明方式:int a[];
int[] a;
double b[];
String[] c ; //引用类型变量数组
Java语言中声明数组时不能指定其长度(数组中元素的数),
例如: int a[] = new int[]; //非法int a[] = new int[5];初始化值
是不能指定长度的,后面的= new int[5]是在进行初始化数组,非法的原因是没有指定初始化的长度,与定义时指定长度无关;
可以存储多个数据而且有下标从0开始,方便操作这些元素,我们可以通过length属性获取数组长度
1)可以存储任意类型的数据
2)数组大小一旦确定就无法改变
3)可以通过下标获取数据
格式:数据类型[] 数组名 = new 数据类型[元素个数或数组长度];
案例:int[] arr = new int[3];
arr[0] = 3;
arr[1] = 9;
arr[2] = 8;
说明:声明一个数组用来存放int类型的数据,可以存储5个
格式:数据类型[] 数组名 = new 数据类型[]{元素,元素,……};
案例1:int[] arr = new int[]{3,5,1,7};
案例2:int[] arr = {3,5,1,7};
说明:以上两种写法都相同,下边的是简写方式
当我们确定要存储哪些数据时可以使用静态声明因为比较方便,如果我们不确定要存储哪些具体的数据,需要使用动态声明后期赋值。当然静态声明方式也是可以修改值的
增强for循环操作起来比较方便,但是不能通过下标操作元素,所以仅当需要遍历时可以使用增强for循环,如果要操作元素还是需要使用普通的循环,通过下标操作元素。
public static void main(String[] args) {
int[] x = { 1, 2, 3 };
System.out.println(x[3]);
//异常:java.lang.ArrayIndexOutOfBoundsException
}
说明:当操作了不存在的角标时会出现角标越界异常,
解决:我们可以通过数组的length属性控制循环时的角标,防止越界。
public static void main(String[] args) {
int[] x = { 1, 2, 3 };
x = null;
System.out.println(x[1]);
//空指针异常: java.lang.NullPointerException
}
说明:因为数组时引用数据类型所有有一个特殊的值是null,如果值为(引用)为null再去使用该变量时就会出现空指针异常。
解决:可以通过判断确定如果不是null再做操作,如果是null则给出提示
Java提供的专门用来操作数据的类,可以对数组进行排序,查询,拷贝等操作
public class ArraysTest {
public static void main(String[] args) {
int[] arr = {22,12,45,66,98,54,33};
/*
* 作用:对所有的元素进行升序排序
* 参数:要排序的数组
*/
Arrays.sort(arr);
/*
* 作用:对数组中指定区间的元素进行升序排序
* 参数1:要排序的数组
* 参数2:要排序的开始下标(索引)包含
* 参数3:要排序的结束下标,不包含
*/
//Arrays.sort(arr, 2, 7);
/*
* 作用:将数组变成字符串表现形式
* 参数1:要转成字符串的数组
* 返回值:String类型的字符串
*/
/*String str = Arrays.toString(arr);
System.out.println("toString:"+str);*/
/*
* 作用:根据二分查询查找指定的元素所在的下标
* 参数1:要查询的数组
* 参数2:要查询的元素
* 返回值:元素的下标
* 没有该元素返回负数:返回的是要插入位置-(下标)-1
*/
int index = Arrays.binarySearch(arr, 100);
System.out.println("查询:"+index);
/*
* 作用:将指定数组中的元素复制到另一个数组中
* 参数1:要复制的数组
* 参数2:新数组的长度
* 返回值:返回一个新的数组,数组的类型与被复制的数组类型相同,没有的值使用默认值填充
*/
int[] copy_arr = Arrays.copyOf(arr, 7);
System.out.println("copy_arr:"+Arrays.toString(copy_arr));
/*
* 作用:拷贝指定数组的指定下标的元素
* 参数1:被拷贝的数组
* 参数2:开始位置
* 参数3:结束位置
* 返回值:一个新数组
*/
int[] copy_arr2 = Arrays.copyOfRange(arr, 2, 6);
System.out.println("copy_arr2:"+Arrays.toString(copy_arr2));
/*
* 作用:比较两个数组中的元素是否一致
* 参数1:要比较的数组1
* 参数2:要比较的数组2
* 返回值:boolean类型,
*/
boolean b = Arrays.equals(arr, copy_arr);
System.out.println("equale:"+b);
/*
* 作用:将数组使用指定的值填充
* 参数1:要填充的数组
* 参数2:要填充的元素数据
*/
Arrays.fill(copy_arr, 100);
System.out.println("fill:"+Arrays.toString(copy_arr));
}
}
所谓的二维数组就是数组中存储了一个数组,其实还有三维四维等
数组类型[][] 数组名 =
new 数组类型[一维数组的个数][每一个一维数组中元素的个数];
定义在类中具备一定功能的代码块 main(){ }
1)提高代码的复用性
2)将程序进行封装,提高程序的安全性
访问修饰符 返回值类型 方法名([数据类型 变量1,数据类型 变量2,...]){
要执行的代码;
return 返回值;
}
0.访问修饰符:控制方法的访问权限,现阶段都写成public static
1.返回值类型:
1.有返回值,返回值类型与返回值的类型一致
2.没有返回值,返回值类型使用void表示
2.方法名:自己定义的名字,符合规范并且有意义(顾名思义)
3.参数列表:
数据类型:该方法接收的参数的数据类型
变量1:自定义的变量名,有意义
4.要执行的代码:该方法所要完成的功能
5.return两个作用:
1.将方法的返回值返回给调用者
2.结束方法
6.返回值:方法运算完之后的结果,可以通过return关键字返回给调用者,交由调用者处理
1.有参数有返回值
2.有参数没有返回值
3.没有参数有返回值
4.没有参数没有返回值
内存图
1)传递基本数据类型:相当与一个值拷贝的的过程,会在栈内存中开辟一块空间保存新的变量,操作的是新变量而原先的值并不发生变化。
2)传递引用数据类型:会将堆内存中的地址传递给新变量,操作时操作的是同一块内存中的数据,所以原数据会发生变化。
0.方法只能定义在类中
1.方法中只能调用方法,不能定义方法
2.方法只有被调用才执行,不调用就不执行
3.方法的返回值返回给调用者,将结果交给调用者处理
1.如果有未知数参与运算就需要在定义方法时定义参数列表,明确参数类型就是数据类型,
明确有几个未知数参与运算就是明确有几个形式参数
2.明确方法运算完之后如果调用者需要结果则明确返回值类型,否则返回值类型就是用void来写
如果调用者需要返回值,返回值类型就根据返回值来写
形式参数:方法定义上声明的变量
实际参数:方法调用时传递的具体的数据
概念:在同一个类中,方法名相同,但是参数列表不同,与返回值类型无关,与参数的顺序有关
案例:计算两个数的和,计算三个数的和
好处:有些方法它们的功能相同,但是实现的方式不同,为了让方法名更有意义,java提供了一个机制,叫做方法的重载
什么时候使用:
当一个类中有部分方法他们的功能是相同的但是实现方式不同就可以将这写方法的方法名定义成一样的
