java方法和数组
一. 方法
1.1 什么是方法
- System.out.println(),那么它是什么呢?
- Java方法是语句的集合,它们在-起执行一个功能。
- 方法是解决-类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
- 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的
时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
回顾:方法的命名规则
首字母小写,保持驼峰原则
1.2 方法的定义
- Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,-般情况下,定义
一个方法包含以下语法: - 方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有
返回值。在这种情况下,returnValueType 是关键字void。 - 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的
参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。- 形式参数:在方法被调用时用于接收外界输入的数据。
- 实参:调用方法时实际传给方法的数据。
- 方法体:方法体包含具体的语句,定义该方法的功能。
public static int add(int a, int b) {
return a + b;
}
1.3 方法调用
- 调用方法:对象名.方法名(实参列表)
- Java支持两种调用方法的方式,根据方法是否返回值来选择。
- 当方法返回一个值的时候,方法调用通常被当做-个值.例如:
int larger = max(30, 40);
- 如果方法返回值是void,方法调用-定是-条语句.
System.out.print1n("Hello");
- 课后拓展了解:值传递(java)和引用传递
- 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
- 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
- 错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。
- 错误理解二:Java是引用传递。
- 错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。
1.4 方法的重载
- 重载就是在-个类中,有相同的函数名称,但形参不同的函数。
- 方法的重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为方法的重载。
- 实现理论:
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对
应的方法,如果匹配失败,则编译器报错。
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对
1.5 命令行传参
有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
在src目录下执行:java 文件路径.文件名
1.6 可变参数
- JDK 1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(...)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public static void main(String[] args) {
Test4 test4 = new Test4();
test4.test(1,5,6,8);
}
public void test(int j,int... i){
System.out.println(j);
System.out.println(i[0]);
}
1.7 递归
- A方法调用B方法,我们很容易理解!
- 递归就是: A方法调用A方法!就是自己调用自己
- 利用递归可以用简单的程序来解决一些复杂的问题。 它通常把一个大型复 杂的问题层层转化为
一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所
需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象
的无限集合。
- 递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
//阶乘
//2! 2*1
//3! 3*2*1
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n){
//边界条件
if (n==0){
return 1;
}else{
//返回阶段
return n*f(n-1);
}
}
二. 数组
2.1 数组的定义
- 数组是相同类型数据的有序集合.
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.
2.2 数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量.
数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是!其他对象类型,
数组对象本身是在堆中的。
2.3 数组的声明创建
- 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar;//首选的方法
dataType arrayRefVar[]; // 效果相同,但不是首选方法
- Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
- 数组的元素是通过索引访问的,数组索引从0开始。
- 获取数组长度:
arrays. length
2.4 数组初始化方法
2.4.1 静态初始化
//静态初始化
int[] a={0,2,3,4,5,6,7,8,9};
System.out.println(a[0]);
2.4.2 动态初始化
int[] b=new int[10];
b[0]=10;
System.out.println(b[0]);
2.4.3 默认初始化
动态初始化中未被赋值的单位进行默认初始化
ArrayIndexOutOfBoundsException :数组下标越界异常!
2.5 数组的使用
- for循环
int[] a = {0, 2, 3, 4, 5, 6, 7, 8, 9};
//打印全部数组元素
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
- For-Each循环
//jdk1.5,没有下标
int[] arrays = {0, 1, 2, 3, 4, 5, 6};
for (int array : arrays) {
System.out.println(array);
}
- 数组作方法入参
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i] + "");
}
}
- 数组作返回值
///反转数组
public static int[] reverse(int[] arrays) {
int[] res = new int[arrays.length];
for (int i = 0, j = res.length - 1; i < arrays.length; i++, j--) {
res[j] = arrays[i];
}
return res;
}
2.6 多维数组
- 多维数组可以看成是数组的数组,比如维数组就是一 个特殊的一维数组,其每一个元素都是
一个一维数组。 - 二维数组
int a[][] = new int[2][5];
- 解析:以上二维数组a可以看成一个两行五列的数组。
- 思考:多维数组的使用?
2.7 Arrays类
- 数组的工具类java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了-个工具类Arrays供我们使
用,从而可以对数据对象进行一些基本的操作。
查看JDK帮助文档 - Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不
用"使用对象来调用(注意:是"不用”而不是“不能") - 具有以下常用功能:
- 给数组赋值:通过fill方法。
- 对数组排序:通过sort方法,按升序。
- 比较数组:通过equals方法比较数组中元素值是否相等。
- 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
int[] a={1,2,5,9,7,3,6,7,8};
System.out.println(a);
System.out.println(Arrays.toString(a));//[1, 2, 5, 9, 7, 3, 6, 7, 8]
Arrays.sort(a);
System.out.println(Arrays.toString(a));//[1, 2, 3, 5, 6, 7, 7, 8, 9]
Arrays.fill(a,0);
System.out.println(Arrays.toString(a));//[0, 0, 0, 0, 0, 0, 0, 0, 0]
2.8 冒泡排序
- 冒泡排序无疑是最为出名的排序算法之一, 总共有八大排序!
- 冒泡的代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。
- 我们看到嵌套循环,应该立马就可以得出这个算法的时间复杂度为O(n2)。
public static void sort(int[] array) {
//外层循环,判断我们要走多少次
//临时变量
int temp = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i-1; j++) {
if (array[j + 1] < array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
- 思考:如何优化?
(待优化??)
public static void sort(int[] array) {
int temp = 0;
boolean flag=false;//通过flag表示为没有意义的比较
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i-1; j++) {
if (array[j + 1] < array[j]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag=true;
System.out.println("第"+(j+1)+"位数:"+array[j+1]+"与"+"第"+j+"位数:"+array[j]+"进行交换");
}
}
System.out.println("--------------------");
if (flag==false){
break;
}
}
}
2.9 稀疏数组
- 需求:编写五子棋游戏中,有存放退出和续上盘的功能
- 分析问题:因为二维数组中很多只都是默认为0,因此记录了很多没有意义的数值
- 稀疏数组
2.9.1 稀疏数组介绍
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组.
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 吧具有不痛值的援素 和行列及值记录在一个规模的数组种 ,从而缩小程序的规模
数组
| 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 |
| 0 | 4 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 8 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 4 | 0 | 0 | 0 |
| 0 | 4 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
稀疏数组
| * | 行 | 列 | 值 |
| [0] | 8 | 8 | 6 |
| [1] | 0 | 4 | 2 |
| [2] | 1 | 1 | 4 |
| [3] | 2 | 0 | 1 |
| [4] | 2 | 3 | 8 |
| [5] | 3 | 4 | 4 |
| [6] | 4 | 1 | 4 |
具体代码
public static void main(String[] args) {
//创建一个二维数组 11*11 0没有棋子 2白棋
int row = 8;//列
int col = 8;//行
int[][] array1 = new int[col][row];
array1[0][4] = 2;
array1[1][1] = 4;
array1[2][0] = 1;
array1[2][3] = 8;
array1[3][4] = 4;
array1[4][1] = 4;
System.out.println("输出原始的数组");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
//转换为稀疏数组
//获取有效值的个数
int sum = 0;
for (int i = 0; i < col; i++) {
for (int i1 = 0; i1 < row; i1++) {
if (array1[i][i1] != 0) {
sum++;
}
}
}
System.out.println("有效值的个数:" + sum);
//2.创建一个稀疏数组
int[][] array2 = new int[sum + 1][3];
array2[0][0] = col;
array2[0][1] = row;
array2[0][2] = sum;
//遍历二维数组,将非零的值,存放在稀疏数组种
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int i1 = 0; i1 < array1[i].length; i1++) {
if (array1[i][i1] != 0) {
count++;
array2[count][0] = i;
array2[count][1] = i1;
array2[count][2] = array1[i][i1];
}
}
}
//输出稀疏数组
System.out.println("稀疏数组");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0] + "\t"
+ array2[i][1] + "\t"
+ array2[i][2] + "\t"
);
}
System.out.println("还原数组");
//读取稀疏数组
int[][] array3=new int[array2[0][0]][array2[0][1]];
//给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]]=array2[i][2];
}
//打印
System.out.println("输出还原的数组");
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
}
浙公网安备 33010602011771号