Java语言基础学习笔记(四)

本文主要探讨Java语言的基础,包括方法的设计与执行流程,如方法定义、方法重载和递归操作。此外,还深入讲解了一维数组的定义、初始化、操作及内存分析,涵盖了数组的静态和动态初始化,以及获取、设置、遍历数组元素的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、语言基础---4.方法和数组

(一)方法设计

循环操作:解决的是代码重复的问题,用来处理重复做某一件事情。此时的重复:有规律,语句格式是相同的,有规律的

循环操作能解决所有的重复吗?

针对某一种功能的重复操作,循环解决不了,此时得使用方法

078、方法定义和基本调用操作

方法(method),函数(function):指一个特定的功能操作,程序中完成独立功能,可重复使用的一段代码的集合;

方法定义格式:

[修饰符] 方法的返回值类型 方法名称([形式参数1,形式参数2,...])

  {

       方法体;

       [return 值]; //方法需要给调用者返回一个结果

  }

方法必须要调用才能生效(看着菜单点菜),main方法专门由JVM来负责调用,我们只管启动JVM

如果方法使用了static修饰:此时使用方法所在类的名称.方法名(参数);

如果方法没有使用了static修饰:此时使用方法所在类的对象来调用(面向对象)

方法定义的位置:

1)在类中定义,在Java中最小的程序单元是类

2)方法定义在其他方法之外,方法和方法是兄弟关系

3)方法定义的先后顺序不影响

//方法的定义和调用
public class MethodDemo 
{
	//把共同的200行代码,抽离到方法中
	static void doWork()
	{
		System.out.println("共同的200行代码");	
	}
	public static void main(String[] args) //主方法
	{
		System.out.println("代码片段A");
		MethodDemo.doWork(); //调用方法
		System.out.println("代码片段B");
		MethodDemo.doWork(); //调用方法
		System.out.println("代码片段C");
		MethodDemo.doWork(); //调用方法
		System.out.println("代码片段D"); 
	}
}

079、方法中的专业术语

修饰符:public,static等,决定了方法的访问权限。static表示方法属于类,直接使用类名调用即可,现在都使用static修饰

返回值类型:方法其实是完成一个功能。该功能操作完毕之后,是否需要给调用者返回一个结果(过程/结果)

                      如果不需要给调用者返回结果,使用关键字void来声明,无返回的意思

方法名称:遵循标识符的规范。使用动词短语表示,首字母小写,若是多个单词组成,使用驼峰表示,例如:doWork

形式参数:方法圆括号中的变量,仅仅只是占位而已。参数的名称其实无所谓,形式参数可以有多个

 参数列表:参数列表==参数类型+参数个数+参数顺序

方法签名:方法签名==方法名称+方法参数列表。在同一个类中,方法签名是唯一的

方法体:方法{}中的代码,表示具体完成该功能的代码

返回值:在方法内部,使用return关键字。功能1:给调用者返回一个结果,此时该方法不能使用void修饰;功能2:结束当前方法

实际参数:调用者在调用某一个具体方法的时候,实际传递的参数值

方法的调用者:在哪里调用某一个方法,那么哪里就是该方法的调用者

080、如何定义/设计方法

如何定义方法:

1)到底要定义什么功能方法,刚开始不要太纠结,慢慢来

2)是否需要定义返回值类型?

       方法其实就是在完成某一个功能, 那么完成该功能之后,是否需要给调用者返回一个结果数据,如果不需要返回结果数据,此时使用void声明(无返回)

       如果需要返回一个结果数据,就把该结果数据的类型作为该方法的返回值类型

       打印操作:在乎的是方法执行的过程,而不是结果,所以此时使用void声明

      求两个数之和:此时在乎的是方法执行的过程,并且执行完毕之后,需要给调用者一个反馈

3)是否需要形式参数?

      该方法在完成该功能的过程中,是否有未知的因素参与,如果有请作为参数传递,如果没有则没有形参

      求两个数之和:这两个数到底是多少,对于方法来说是未知的,仅仅是调用者知道,而且不同的调用者传递不同的参数值

针对于有返回值的方法,调用者应该定义一个变量去接收返回的结果。

//方法的定义和调用
public class MethodDemo2 
{
		//a无参数无返回
		//需求:定义一个方法,专门打印-------
		static void p()
		{
			System.out.println("------------");
		}
		//b有参数无返回
		//需求:定义一个方法,打印任意值
		static void pValue(String val)
		{
			System.out.println(val);
		}
		//c无参数有返回
		//需求:返回年龄(17)
		static int getAge()
		{
			return 17;
		}
		//d有参数有返回
		//需求:求两个数之和
		static int getSum(int a, int b)
		{
			return a + b;
		}
	public static void main(String[] args) 
	{
		MethodDemo2.p(); //调用方法
		MethodDemo2.pValue("123"); //调用pValue方法,传递123字符串
		int age = MethodDemo2.getAge(); //定义age变量,接收getAge方法返回结果
		System.out.println(age);
		int sum = MethodDemo2.getSum(1 , 2); //定义sum变量,接收getSum方法返回结果
		System.out.println(sum);
	}
}

081、方法的执行流程分析

082、方法设计练习(发短信和登录)

083、方法重载设计

重载方法(overload):在同一个类中,某方法允许存在一个以上的同名方法,只要他们的参数列表不同即可

作用:屏蔽了同一功能的方法由于参数不同所造成方法名称不同的差异

原则:两同一不同。同类中,方法名相同;方法参数列表不同(参数类型、参数个数、参数顺序)

注意:重载方法和方法的返回值类型无关,只是一般要求返回值类型一致

           参数列表和参数名称没有关系,方法的重载和形参没有关系

//方法的定义和调用
// 方法重载
public class OverLoadDemo 
{
	//求两个整数之和
	static int getSum(int x, int y)
	{
		return x + y;
	}
	//求两个小数之和
	static double getSum(double x, double y)
	{
		return x + y;
	}
	//打印string
	static void p(String data)
	{
		System.out.println(data);
	}
	//打印int
	static void p(int data)
	{
		System.out.println(data);
	}
    static void p()
	{
		
	}
	public static void main(String[] args) 
	{
		OverLoadDemo.getSum(1 , 2); //调用getSum(int x, int y)
		OverLoadDemo.getSum(1.0 , 2.0); //调用getSum(double x, double y)
        OverLoadDemo.p(123);
        OverLoadDemo.p("asd");
	}
}

084、方法重载在JDK中的使用

同一个类中,不能存在两个相同的方法

085、方法的递归操作

自己调用自己

//递归操作
public class RecursionDemo 
{
	public static void main(String[] args) 
	{
		int ret = fn(5);
		System.out.println(ret);
	}
	//斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
	static int fn(int n)
	{
		if (n == 0)
		{
			return 0;
		}
		else if(n == 1)
		{
			return 1;
		}
		else
		{
			return fn(n - 1) + fn(n - 2);
		}
	}
}

(二)JVM内存模型

086、JVM内存模型

JVM内存划分,人为的根据不同内存空间的存储特点以及存储的数据

1)程序计数器:当前线程所执行的字节码的行号指示器

2)本地方法栈:为虚拟机使用的native方法事务

3)Java虚拟机栈(Stack):描述Java方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息(last in,first out)

       每一个方法,创建一个栈帧,栈帧存放了当前方法的数据信息(局部变量),当方法调用完毕,该方法的栈帧就被销毁了

4)Java堆(Heap):被所有线程共享的一块内存区域,在虚拟机启动时创建。所有对象实例以及数组都要在堆上分配(使用new关键字,就表示在堆中开辟一块新的存储空间)

5)方法区:线程共享的内存区域,存储已被虚拟机加载的类信息、常量、静态变量即时编译器编译后的代码数据等(这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载)

GC(Garbage Collection):垃圾回收器。Java的自动垃圾回收机制:当JVM发现内存资源紧张的时候,就会自动地去清理无用对象(没有被应用到的对象)所占用的内存空间。

                                             (Java的自动垃圾回收器,自动回收的是堆空间的内存;而栈空间内存会随着该方法的执行结束,自动释放该方法的栈帧内存)

(三)一维数组

087、引出数组和数组的定义

数组:一组(堆)数据。所谓数组,是在程序设计中,为了方便处理,把具有相同类型的若干变量按有序的形式组织起来的一种数据形式。按一定顺序排列的同类型数据的集合称为数组。

数组中的每一个数据称为数组元素,数组中的元素以索引来表示其存放的位置,索引从0开始,步长是1,逐行递增。

数据类型:基本数据类型(byte、short、int、long、float、double、char、blooean)和引用数据类型(类、接口、数组)

变量的定义:数据类型 变量名;如:int age;

数组的定义:

方式1:数组元素的类型[] 数组名; 如:int [] ages;

方式2:数组元素的类型 数组名[]; 如:int ages[];

数组必须先初始化才能使用,因为初始化表示在内存中分配空间

//数组的定义
public class ArrayDemo 
{
	public static void main(String[] args) //args:参数(arguments)
	{
		//表示一个变量
		int age;
		//表示全班同学的年龄
		int[] ages1; //推荐,把int[]看成是一种int类型的数组类型
		int ages2[];		
		//System.out.println(ages1); //ArrayDemo.java:12: 错误: 可能尚未初始化变量ages1
	}
}

088、数组的静态初始化和内存分析

Java中数组必须初始化后才能使用,所谓初始化就是给数组元素分配内存,并为每个元素赋初始值

初始化数组,不论哪种初始化,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化(数组是定长的(数组元素的个数固定))

1)数组的静态初始化:为每一个数组元素设置初始值,而数组的长度由系统(JVM)分配

//数组的初始化
public class ArrayInitDemo 
{
	public static void main(String[] args) //args:参数(arguments)
	{
		//语法:数组元素类型[] 数组名 = new 数组元素类型[] {元素1,元素2, 元素3,......};
		int[] nums = new int[]{1,3,5,7,9}; 
		//简单写法:int[] nums = {1,3,5,7,9};必须声明之后,立即初始化,不能先声明后初始化
		System.out.println(nums.length); //5 打印出数组的长度
		nums = new int[] {2,4,8};
		System.out.println(nums.length); //3
	}
}

内存分析:

2)数组的动态初始化:设置数组的元素个数(数组长度),而每一个数组元素的初始值由系统决定

//数组的初始化
public class ArrayInitDemo2 
{
	public static void main(String[] args) //args:参数(arguments)
	{
		//语法:数组元素类型[] 数组名 = new 数组元素类型[length];
		int[] nums = new int[3]; 
		System.out.println(nums.length); // 3
		nums = new int[5];
		System.out.println(nums.length); // 5
	}
}

不能同时使用静态初始化和动态初始化

什么时候使用静态初始化?什么时候使用动态初始化?

当事先知道需要存储哪一些数据的时候,选用静态初始化;事先不知道需要存储哪一些数据的时候,选用动态初始化

090、获取、设置、遍历数组元素

数组的基本操作:

1.获取元素:元素类型 变量 = 数组名[index]

2.设置元素:数组名[index] = 值;

3.遍历数组元素:建议使用for循环,事先知道循环的次数

4.数组长度:数组名.length;  length是属性,不是方法

5.索引范围:从0开始,逐一递增。 [0,数组名.length]

//数组的操作
public class ArrayOperateDemo 
{
	public static void main(String[] args) //args:参数(arguments)
	{
		int[] nums = new int[]{1,3,5,7,9};
		System.out.println("数组的长度=" + nums.length); //数组的长度=5
		System.out.println("数组的第一个元素=" + nums[0]); //数组的第一个元素=1
		System.out.println("数组的最后一个元素=" + nums[4]); //数组的最后一个元素=9
		nums[0] = 100; //修改nums数组的第一个元素
		System.out.println("数组的第一个元素=" + nums[0]); //数组的第一个元素=100
		//遍历数组元素
		for (int index = 0; index < nums.length ; index ++ )
		{
			System.out.println(nums[index]); //100/3/5/7/9
		}
		boolean[] bs = new boolean[3];
		for (int index = 0; index < bs.length ; index ++ )
		{
			System.out.println(bs[index]); //false/false/false
		}
		String[] str = new String[3];
		for (int index = 0; index < bs.length ; index ++ )
		{
			System.out.println(str[index]); //null/null/null
		}
		double[] db = new double[3];
		for (int index = 0; index < db.length ; index ++ )
		{
			System.out.println(db[index]); //0.0/0.0/0.0
		}
	}
}

091、操作数组的常见异常

1. NullPointerException:空指针异常(空引用)。当数组还没有初始化,就直接操作数组

2.ArrayIndexOutOfBoundsException:数组索引越界异常

//数组的常见异常
public class ArrayExceptionDemo
{
	public static void main(String[] args) //args:参数(arguments)
	{
		//空指针异常
		int[] nums = null;
		//System.out.println(nums.length); // Exception in thread "main" java.lang.NullPointerException
		nums = new int[] {2,4,8};
		System.out.println(nums[1]); //4
		//数组索引越界异常
		System.out.println(nums[5]); //Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	}
}

092、获取数组中的最大和最小元素

//数组的操作
public class ArrayOperateDemo2 
{
	//获取数组最大元素
	static int getMax(int[] nums)
	{
		int max = nums[0]; //假设第一个元素是最大值
		for (int index = 1; index < nums.length ; index ++ )
		{
			if (nums[index] >max)
			{
				max = nums[index]; //把最大值存储在max变量里
			}
		} 
		return max;
	}
	//获取数组最小元素
	static int getMin(int[] nums)
	{
		int min = nums[0]; //假设第一个元素是最小值
		for (int index = 1; index < nums.length ; index ++ )
		{
			if (nums[index] < min)
			{
				min = nums[index]; //把最小值存储在min变量里
			}
		}
		return min;
	}
	public static void main(String[] args) //args:参数(arguments)
	{
		int[] nums = new int[]{-3,5,0,2,1,10};
		int max = ArrayOperateDemo2.getMax(nums);
		System.out.println(max); //10
		System.out.println(ArrayOperateDemo2.getMin(nums)); //-3
	}
}

093、按格式打印数组元素

直接打印数组,打印出来的是hashcode。如数组{-3,5,0,2,1,10}打印结果为:[I@1db9742

//数组的操作
public class ArrayPrintDemo
{
	public static void main(String[] args) //args:参数(arguments)
	{
		String[] nums = new String[]{"-3","5","0","2","1","10"};
		System.out.println(nums); //[Ljava.lang.String;@1db9742
		ArrayPrintDemo.printArray(nums); //[-3,5,0,2,1,10]
	}
	static void printArray(String[] arr)
	{
		if (arr == null)
		{
			System.out.println("null");
			return; //结束方法
		}
		String ret = "[";
		for (int index = 0; index < arr.length ; index ++ )
		{
			ret = ret + arr[index];
			if (index != arr.length - 1) //如果当前index不是最后一个索引,则拼接“,”
			{
				ret = ret + ",";
			}
		}
		ret = ret +"]";
		System.out.println(ret);
	}	
}

094、逆序排列数组元素

//数组的逆序排序
public class ArrayReverseDemo
{
	public static void main(String[] args) //args:参数(arguments)
	{
		String[] arr = {"A","B","C","D","E","F"};
		ArrayReverseDemo.reverse(arr); //调用逆序方法
		String[] newArr = ArrayReverseDemo.reverse(arr);
		ArrayReverseDemo.printArray(newArr);
		
	}
	static void printArray(String[] arr)
	{
		if (arr == null)
		{
			System.out.println("null");
			return; //结束方法
		}
		String ret = "[";
		for (int index = 0; index < arr.length ; index ++ )
		{
			ret = ret + arr[index];
			if (index != arr.length - 1) //如果当前index不是最后一个索引,则拼接“,”
			{
				ret = ret + ",";
			}
		}
		ret = ret +"]";
		System.out.println(ret);
	}	
	static String[] reverse(String[] oldArr)
	{
		//创建一个新的数组,存放逆序之后的元素
		String[] newArray = new String[oldArr.length];
		for (int index = oldArr.length - 1; index >=0 ; index -- )
		{
			newArray[oldArr.length - 1 - index] = oldArr[index];
			
		}
			return newArray;
	}	
}

095、元素出现索引(线性搜索)

//元素出现索引
public class ArraySearchDemo 
{
	/*
	int[] arr = {10,20,30,10,50,30,10};
	获取元素10在arr数组中第一次出现的索引(indexOf); //0  从前往后找,第一个
	获取元素10在arr数组中最后一次出现的索引(lastIndexOf); //6  从后往前找,第一个
	*/
	public static void main(String[] args) 
	{
		int[] arr = {10,20,30,10,50,30,10};
		int beginIndex = ArraySearchDemo.indexOf(arr, 10);
		System.out.println(beginIndex); //0
		System.out.println(ArraySearchDemo.lastIndexOf(arr, 10)); //6
	}
	/*查询key元素在arr数组中第一次出现的位置
	参数:
		arr:从哪一个数组中去做查询
		key:当前去查询的元素
	返回:如果key存在与arr数组中,则返回第一次出现的索引。key不存在于arr数组中,则返回-1
	*/
	static int indexOf(int[] arr, int key)
	{
		for (int index = 0; index < arr.length; index ++ )
		{
			if(arr[index] == key);
			{
				return index;
			}
		}
		return -1;
	}
	//判断key在arr数组中最后出现的次数
	static int lastIndexOf(int[] arr, int key)
	{
		for (int index = arr.length -1; index >= 0 ; index -- ) //先找最后一个元素,一直进行减减操作
		{
			if(arr[index] == key);
			{
				return index;
			}
		}
		return -1;
	}
}

096、小结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值