方法
方法的定义
方法(又叫函数)就是一段特定功能的代码块。方法提高程序的复用性和可读性。
方法是Java程序设计中的重要概念之一,它是一种代码复用的方式。方法使得我们可以将一组特定任务打包成一个可单独执行的代码块,这些代码块可以在程序的任何地方调用,从而避免了代码的重复编写和冗余。
下面具体介绍一下为什么要有方法:
-
提高代码的可读性和可维护性:通过把功能分解到不同的方法中,可以更容易地理解和维护代码。如果一个方法不起作用,只需要检查该方法本身,而不用去检查整个程序。
-
降低代码的复杂度:方法可以将复杂的任务分解成一些小的、独立的部分,从而降低代码的复杂度,使代码更加易于阅读和修改。
-
提高代码的可复用性:方法可以被多次调用,因此可以在程序的任何地方使用已经编写好的代码,避免了重复编写相同的代码。
-
使代码更加模块化:方法使得代码的功能更加模块化,每个方法都扮演着特定的角色。这种模块化的设计使得代码更加灵活和易于扩展。
方法的格式
语法: 访问权限修饰符 [其他的修饰符 如static] 返回值类型 方法名(参数类型1 形参1,参数类型2 形参2,...){ //形参列表 //方法体 return 返回值; }
-
修饰符:用于控制方法的访问级别,常用的修饰符包括
public
、private
、protected
等。 -
返回类型:指定方法返回值的数据类型,如果方法不返回任何值,则使用
void
表示。 -
方法名:方法的名称,用来唯一标识方法。
-
参数列表:指定传递给方法的参数,可以包含零个或多个参数,每个参数由数据类型和参数名组成。
-
方法体:包含实际执行任务的代码块。
方法的形参与实参
-
实际参数:就是实际参与运算的。
-
形式参数;就是方法定义上的,用于接收实际参数的。
-
参数类型:就是参数的数据类型
-
参数名:就是变量名
-
方法体语句:就是完成功能的代码。
形参就是一个变量,实参就是一个值,传参就是把一个值给一个形参赋值
下面是一个示例,演示了方法的形参和实参的使用:
public class Example { public static void main(String[] args) { int num1 = 5; int num2 = 7; int sum = addNumbers(num1, num2); // 将num1和num2作为实参传递给方法 System.out.println("Sum: " + sum); } public static int addNumbers(int a, int b) { // a和b为形参 int sum = a + b; return sum; } }
方法的返回值
return:结束方法的。
返回值:就是功能的结果,由return带给调用者。
注意:
-
若当前方法没有返回值类型,即返回值类型是void,那么当前方法中可以不写return
-
return即表示结束一个方法,也可以将返回值返回给调用当前方法的调用者
-
return返回值时一次只能返回一个值,不可以返回多个值
-
一个方法中可以有多个return,但被执行的只能有一个,所以需要判断
方法的重载
方法重载:overloading method 在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义; 返回值不能作为重载的条件。 如:
-
public void method(int a){…}
-
public void method(char c){…
数组
数组的定义
-
数组:一组能够存储相同数据类型值的变量的集合。
-
当我们有一组相同类型的数据需要存储,如果此时使用单个变量来存储,我们将要定义若干个变量名,这样将会 非常繁琐,并不利于维护
数组的赋值方式
四种:
-
int [] scores = new int[3];
-
scores = new int[3];
-
int [] scores = new int[]{56,78,98};
-
int [] scores = {56,78,98}
数组的遍历
当遍历 Java 数组时,我们可以使用不同的循环结构来实现。下面是一些常见的遍历数组的示例:
-
使用 for 循环遍历数组:
int[] array = {1, 2, 3, 4, 5}; for (int i = 0; i < array.length; i++) { System.out.println(array[i]); }
-
使用增强型 for 循环遍历数组(也称为 for-each 循环):
int[] array = {1, 2, 3, 4, 5}; for (int num : array) { System.out.println(num); }
-
使用 while 循环遍历数组:
int[] array = {1, 2, 3, 4, 5}; int i = 0; while (i < array.length) { System.out.println(array[i]); i++; }
-
使用 do-while 循环遍历数组:
int[] array = {1, 2, 3, 4, 5}; int i = 0; do { System.out.println(array[i]); i++; } while (i < array.length);
无论使用哪种循环方式,都可以通过数组的索引来访问数组中的元素并进行相应的操作。在循环中,可以根据需要使用元素的值进行逻辑判断、计算或其他处理。
数组内存结构分析
在Java中,内存分配是自动进行的,由Java虚拟机(
JVM
)负责管理。JVM
将Java
程序执行所需的内存分为几个不同的区域,其中包括方法区、堆、栈和本地方法栈。
-
栈(
Stack
):主要用来存放局部变量。 -
堆(
Heap
)∶凡是new出来的东西,都在堆当中。堆当中的数据有默认值规则∶ a)如果是整数,默认是0 ; b)如果是浮点数,默认是0.0 ; c)如果是字符,默认是u0000
(Unicode
写法); d)如果是布尔值,默认为false
; e)如果是引用类型(包含字符串).默认为null
(空常量)。 -
方法区(
Method Area
)︰存放与.class
相关的信息。 -
本地方法区(
Native Method Area
):与操作系统相关. -
寄存器(
pc Register
): 与CPU
相关,性能极高。
数组内存结构分析:数组是引用类型,会存放在堆内存中
最大最小值算法
public class Main { public static void main(String[] args) { int[] numbers = {3, 9, 2, 6, 1, 8, 5}; // 数组示例 int min = Integer.MAX_VALUE; // 初始化最小值为整型最大值 int max = Integer.MIN_VALUE; // 初始化最大值为整型最小值 for (int i = 0; i < numbers.length; i++) { if (numbers[i] < min) { min = numbers[i]; // 更新最小值 } if (numbers[i] > max) { max = numbers[i]; // 更新最大值 } } System.out.println("最小值: " + min); System.out.println("最大值: " + max); } }
冒泡排序算法
public class BubbleSort { public static void main(String[] args) { int[] arr = {5, 2, 8, 4, 1}; bubbleSort(arr); System.out.println("排序结果:"); for (int num : arr) { System.out.print(num + " "); } } /** * 冒泡排序算法 * @param arr 待排序的整型数组 */ public static void bubbleSort(int[] arr) { int n = arr.length; // 数组的长度 boolean swapped; // 标记是否有元素交换的标志位 for (int i = 0; i < n - 1; i++) { // 外层循环控制比较轮数,每轮处理一个最大元素到正确位置 swapped = false; // 初始化为false,如果此轮没有元素交换,则表示数组已经有序,提前结束排序 for (int j = 0; j < n - 1 - i; j++) { // 内层循环进行相邻元素比较和交换操作 if (arr[j] > arr[j + 1]) { // 如果前一个元素大于后一个元素,交换二者的位置 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swapped = true; // 标志位置为true,表示此轮有元素交换 } } if (!swapped) { // 如果此轮没有元素交换,则数组已经有序,提前结束排序 break; } } } }
算法的基本思想是,重复地比较相邻的两个元素,并将较大的元素向右移动,直到所有的元素按照从小到大的顺序排列。
选择排序算法
选择排序算法是一种简单直观的排序算法。其基本思路是每次从未排序的部分中选择最小(或最大)的元素,然后将其放到已排序部分的末尾。具体步骤如下:
-
遍历待排序数组,设当前位置为i,将i标记为未排序部分的起始位置。
-
在未排序部分中找到最小(或最大)的元素,并记录其位置min_index。
-
将未排序部分的第一个元素与min_index位置上的元素交换位置,即将最小(或最大)的元素放到已排序部分的末尾。
-
i递增1,重复步骤2-3,直到遍历完所有的元素。
-
返回排序后的数组。
选择排序算法的时间复杂度为O(n^2),其中n为待排序数组的长度。该算法的优点是实现简单,不需要额外的空间,但是效率较低,不适用于大规模数据排序。
直接插入排序算法
直接插入排序(Insertion Sort)是一种简单直观的排序算法。其基本思路是将一个待排序的元素依次插入已经有序的元素序列中,最终形成一个新的有序序列。
具体实现步骤如下:
-
首先,将数组分为已排序区和未排序区。初始时已排序区只包含第一个元素,而未排序区包含剩余的 n-1 个元素。
-
从未排序区中取出第一个元素,将其与已排序区的元素从右到左逐个比较,找到合适的位置插入。
-
将该元素插入到已排序区的适当位置后,已排序区元素数量加1,未排序区元素数量减1。
-
重复步骤2和步骤3,直到未排序区元素全部插入到已排序区。
直接插入排序的时间复杂度为O(n^2)(平均情况和最坏情况),空间复杂度为O(1)。尽管在效率上不如快速排序等高级排序算法,但对于小规模数据或基本有序的数据,直接插入排序仍然是一个有效的排序方法。
二分查找算法
(版本一)左闭右闭区间
class Solution { public int search(int[] nums, int target) { // 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算 if (target < nums[0] || target > nums[nums.length - 1]) { return -1; } int left = 0, right = nums.length - 1; while (left <= right) { int mid = left + ((right - left) >> 1); if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else if (nums[mid] > target) right = mid - 1; } return -1; } }
Arrays类
Arrays类是Java标准库中提供的一个工具类,用于操作数组。它提供了一系列静态方法来对数组进行排序、搜索、比较等操作。
代码举例子
总结
在Java中,数组和方法是非常常见且重要的概念。下面是对它们的简要总结:
数组(Array):
-
数组是一种存储相同类型数据的容器,可以容纳固定数量的元素。
-
声明一个数组需要指定元素的类型和数组的名称。
-
数组的长度是固定的,一旦创建后无法改变。
-
数组的索引从0开始,最大索引为长度减1。
-
可以使用下标访问数组中的元素,也可以使用循环遍历数组。
-
Java提供了许多有用的数组操作方法,如排序、查找等。
方法(Method):
-
方法是执行特定任务的代码块,可以接受零个或多个参数,并且可以返回一个值。
-
方法将相关的代码封装在一个独立的单元中,提高了代码的可读性和复用性。
-
方法的声明包括访问修饰符、返回类型、方法名和参数列表。
-
参数列表中的参数类型和顺序必须与方法调用时提供的参数一致。
-
方法可以有返回值,也可以没有返回值(使用
void
关键字表示)。 -
在方法内部可以使用
return
语句返回结果,结束方法的执行。
在使用数组和方法时,需要注意以下几点:
-
数组越界错误:访问数组时要确保索引不会超出数组的范围,否则会抛出
ArrayIndexOutOfBoundsException
异常。 -
方法重载:可以创建具有相同名称但参数列表不同的多个方法,称为方法重载。Java根据参数类型和数量来确定调用哪个方法。
-
数组作为方法参数:数组可以作为方法的参数传递给其他方法,这样可以在方法间共享数据。
-
数组作为方法返回值:方法也可以返回一个数组,使得调用者可以得到计算结果。