疯狂Java学习笔记(007)
回 顾
一、方法:
1. 方法的定义:
什么是方法?拥有特定功能的一个代码段,称为方法,其他语言中称为Function(函数).
2. 方法定义的格式:
public static 返回值类型 方法名(形参类型 参数名1,形参类型 参数名2,....){ 方法体; return [返回值]; }
3.定义方法的两个明确:
1>返回值类型
2>形参列表
4. public static :
方法的修饰符,目前的固定格式。以后会又变化。
5. 返回值类型:
Java中的数据类型(基本的四类八种,引用的:可以又多种多样:jdk提供的,也可以是我们自己定义的!),表示的是方法执行后需要返回值的类型!
如果方法不需要返回任何之,就用void.
6. 方法名:
1>可以理解为变量名;
(就是一段内存空间的标识!方法名就是一段代码的标识!)
2>和变量的命名规范是一致的(即小驼峰命名法,从第二个单词开始首字母大写)
类名和接口名的命名规则是一致的(大驼峰命名法)
联想一下:包名和final变量名:
3>()里整体称为形参列表;
每个形参定义包含两方面:形参类型,形参名!形参之间用逗号分隔,如果方法不需要任何参数,什么都不屑,()必须写!!!
4>形参类型:
任何可用的数据类型:(基本的和引用的都可以)
5>形参名:
就是变量名,这个变量就是在方法体中有效,相当于在方法体中定义的局部变量!!!方法被调用时,形参就被赋值了!按照顺序传值!!!
7. 方法体:
0到若干条可以执行的语句,在方法被调用时,这些语句一次执行!
8. return :
关键字,表示一个方法的结束,如果方法又明确的返回值类型的话,return后必须有一个值(可以和方法定义时的返回值数据类型一致!或者可以自动类型转换成返回值类型的值:变量;常量;表达式)
如果方法的定义中,返回值时void型,return后就不能加任何值!!!
即:return;---此时整条语句都可以省略!!!
9. 方法定义的位置:
类定义中,和main方法时平级关系:
方法中不能再定义其它方法(即:方法不能嵌套定义!!!)
10. 方法的调用:
1>方法调用时传值:
实参:方法调用时,给方法传递的值,就是实参;
形参:方法定义时,参数列表中出现的参数名
2>赋值方向:实参→形参!!!
方法名(实参);
实参的个数一定要和形参的个数对应!
类型:实参要么和形参类型一致,要么可以隐式类型转换!!!
实参的种类:变量,常量,表达式
3> 如何处理方法的返回值:
①有返回值的方法:
-不关心返回值:单独调用
-使用返回值:给其他变量赋值,直接参与表达式运算,当成参数传第给其他方法。
②没有返回值的方法:
-只能单独调用
-不能给其他变量赋值,不能直接参与表达式运算,不能当成参数传第给其他方法。
11. 方法的重载(overload):
两同一不同!!!
即同类,同方法名,形参列表不同(个数不同或者类型的不同都成为形参列表不同!!!)
方法的访问权限修饰符,以及返回值类型都不是判断方法重载的标志!
练习题:
1.定义方法,用于计算一个int数值的阶乘
首先定义:
//返回值类型:int
//形参列表:int value
/* 1.定义方法,用于计算一个int数值的阶乘 //返回值类型:int //形参列表:int value */ public class HomeworkDemo1{ public static void main(String[] abc){ // int res = getNum(5); System.out.println(res); // System.out.println(getNum(5)); } //返回值类型:int //形参列表:int value public static int getNum(int value){ //求阶乘思想: int res = 1; for(int i = 1;i<=value;i++){ res *= i; } return res; } }
2.定义方法,用于获取指定范围内的一个随机值(int)
首先定义:
//返回值类型:int
//形参列表:int start ,int end
/* 定义方法,用于获取指定范围内的一个随机值(int) //返回值类型:int //形参列表:int start,int end
*/ public class HomeworkDemo2{ public static void main(String[] args){ int start = 10; int end = 20; System.out.println("随机值是: " + getRandom(start,end)); } //返回值类型:int //形参列表:int start,int end public static int getRandom(int start,int end){ return (int)(Math.random() * (end - start + 1) + start); } }
/* 定义方法,用于获取指定范围内的一个随机值(int) //返回值类型:int //形参列表:int start,int end 练习: 改造: 从键盘录入起始和结束值: */ import java.util.Scanner; public class HomeworkDemo2{ public static void main(String[] args){ Scanner s = new Scanner(System.in); System.out.print("请输入起始值:"); int start = s.nextInt(); System.out.println("请输入最终值:"); int end = s.nextInt(); System.out.print("随机值是: " + getRandom(start,end)); } //返回值类型:int //形参列表:int start,int end public static int getRandom(int start,int end){ return (int)(Math.random() * (end - start + 1) + start); } }
做练习题
第七天 数组
一、数组
数组的特点
数组定义格式
数组的初始化形式:
/* 数组:array 同一种数据类型的 〇到多个 数据的组合. 数组的数据类型:就是元素的数据类型 数组的长度(length):就是数组中数值的个数: 元素(element):数组的各个数值称为元素 索引(index):数组中各个元素的编号:从0开始,最大值是:数组的长度-1 数组类型是引用数据类型: 数组名保存的是一段内存空间的地址! 真正的元素保存在那段内存空间中!!! 为什么使用数组: 减少定义变量名 方便对一组数据进行操作 定义数组的格式:(即:初始化数组的方式:) 两种: > 定义时不指定初始值:只指定数组的长度,(动态初始化) 数据类型 变量名 = 初始值; 元素类型[] 数组名 = new 元素类型[数组长度]; 例如: 定义一个数组,可以存放5个int型数据. int[] arrInt = new int[5]; > 定义时就指定初始值:(静态初始化) 元素类型[] 数组名 = new 元素类型[]{元素1,元素2,...}; 例如: int[] arr = new int[]{1,2,3,5}; */ public class ArrayDemo1{ public static void main(String[] args){ //定义数组 //动态初始化:定义数组时只指定长度,不指定具体的元素值!! int[] arr1 = new int[5]; //arr1保存的是一段内存地址值! System.out.println(arr1);//[I@15db9742 //打印引用数据类型的结构: //[I : 表示的是数据类型:[ 表示的就是数组,I表示的是元素的类型! //@ : 固定的分隔符 //15db9742 : 一个十六进制的字符串:真实的内存地址值计算出来的!!! //定义byte类型数组 byte[] arr2 = new byte[2]; System.out.println(arr2); boolean[] arr4 = new boolean[3]; System.out.println(arr4); //初始化数组的第二种方式:定义数组时指定元素值!此时不能指定数组的长度! int[] arr3 = new int[]{1,2,3,4,5,6}; System.out.println(arr3); //静态初始化的简化写法: int[] arr5 = {1,2,3,45}; } }
练习:
考察一下,基本数据类型的数组的变量 ,直接打印时,其中的类型是什么字符?
/*
考察基本数据类型的数组变量,直接打印的结果: */ public class ArrayDemo2{ public static void main(String[] args){ byte[] a1 = new byte[2]; short[] a2 = new short[2]; char[] a3 = new char[]{'a','b','c'}; int[] a4 = new int[]{1,2,4}; boolean[] a5 = new boolean[3]; float[] a6 = new float[2]; double[] a7 = new double[2]; long[] a8 = new long[2]; // System.out.println(a1); System.out.println(a2); System.out.println(a3); //println这个方法对字符型的数组有特殊的处理方式:重载这个方法的结果是打印数组里的所有字符! System.out.println(a4); System.out.println(a5); System.out.println(a6); System.out.println(a7); System.out.println(a8); } }
/*
考察基本数据类型的数组变量,直接打印的结果,是内存地址的映射,不是真的内存地址,以十六进制表示:
*/
public class PractiseDemo{ public static void main(String[] args){ System.out.print("int :"); int[] arr1 = new int[5]; System.out.println(arr1); System.out.print("byte :"); byte[] arr2 = new byte[5]; System.out.println(arr2); System.out.print("short :"); short[] arr3 = new short[5]; System.out.println(arr3); System.out.print("long :"); long[] arr4 = new long[5]; System.out.println(arr4); System.out.print("char :"); char[] arr5 = new char[5]; System.out.println(arr5); System.out.print("float :"); float[] arr6 = new float[5]; System.out.println(arr6); System.out.print("double :"); double[] arr7 = new double[5]; System.out.println(arr7); System.out.print("boolean :"); boolean[] arr8 = new boolean[5]; System.out.println(arr8); } }
打印结果:注意long型开始时J,boolean型区别于byte是Z,而char类型字符型的数组有特殊的处理方式:重载这个方法的结果是打印数组里的所有字符!
jvm
如,淘宝自主开发的 Tao JVM
2. jvm如何对内存进行区域的划分:
对内存的划分就是方便对数据的管理:
3. 通常会划分5大区域:
栈区:stack
堆区:heap
方法区:method area
本地方法栈:native method stack(基本不用)
程序计数器:program counter(基本不用)
4. 不同的jvm虚拟机对内存空间的划分是不一样的.
方法中定义的局部变量(和形参)都是在栈区:
栈区中的变量没有初始值,使用之前必须手动赋值!!
2> 堆区:heap
凡是new出来的对象都是在堆区!
Scanner s = new ...
int[] arr = new ...
ps:堆区中的变量都有初始值!!!
3> 方法区:method area
用来存放.class字节码文件和方法定义的!
4. .java -> .class -> 方法区!!
5. 数组的内存结构
5.代码学习
1>定义基本数据类型的数组,查看每种数据类型的默认值,其实有点消极。
整数:0
浮点数:0.0
布尔型:false
引用数据类型:null
1 /* 2 验证: 3 1.数组的默认值: 4 2.数组元素的访问方式: 5 数组名[索引值] 6 练习:定义基本数据类型的数组,有2个元素.考察他们的默认值: 7 8 */ 9 public class ArrayDemo3{ 10 public static void main(String[] args){ 11 //定义一个数组 12 int[] arr = new int[3]; 13 //在堆空间中开辟3个空间,每个空间可以存放一个int型元素.初始值为0. 14 //然后把首元素的地址(也就是整个数组的地址)赋值给栈空间中的变量arr 15 16 //验证默认值: 17 System.out.println(arr[0]); 18 System.out.println(arr[1]); 19 System.out.println(arr[2]); 20 21 //如何对数组元素赋值: 22 arr[2] = 10; 23 System.out.println(arr[2]); 24 25 arr[2] = 20; 26 System.out.println(arr[2]); 27 28 } 29 }
/* 练习:定义基本数据类型的数组,有2个元素.考察他们的默认值: 考察基本数据类型和引用数据类型的数组的默认值! 整数:0 浮点数:0.0 布尔型:false 引用数据类型:null */ public class PractiseDemo{ public static void main(String[] args){ System.out.println("int 默认值为"); int[] a4 = new int[2]; System.out.println(a4[0]); System.out.println(a4[1]); System.out.println("byte 默认值为"); byte[] a1 = new byte[2]; System.out.println(a1[0]); System.out.println(a1[1]); System.out.println("short 默认值为"); short[] a2 = new short[2]; System.out.println(a2[0]); System.out.println(a2[1]); System.out.println("chare 默认值为"); char[] a3 = new char[]{'a','b','c'}; System.out.println(a3[0]); System.out.println(a3[1]); System.out.println("boolean 默认值为"); boolean[] a5 = new boolean[3]; System.out.println(a5[0]); System.out.println(a5[1]); System.out.println("float 默认值为"); float[] a6 = new float[2]; System.out.println(a6[0]); System.out.println(a6[1]); System.out.println("double 默认值为"); double[] a7 = new double[2]; System.out.println(a7[0]); System.out.println(a7[1]); System.out.println("long 默认值为"); long[] a8 = new long[2]; System.out.println(a8[0]); System.out.println(a8[1]); } }
结果为:
1.Java中数组的初始化方式有哪两种?
2.jvm虚拟机的内存划分成几个区域,各个区域都有什么特点?
3.以下每条语句执行时,内存中都发生了什么变化?
int[] arr = new int[2];
arr[1] = 10;
4.定义一个方法,参数是一个int数组.在方法中把所有的元素都打印出来.
回答:
1. 两种:
> 定义时不指定初始值:只指定数组的长度,(动态初始化)
动态初始化:定义数组时只指定数组的长度,里面的元素都是默认值
数据类型 变量名 = 初始值;
元素类型[] 数组名 = new 元素类型[数组长度];
例如:
定义一个数组,可以存放5个int型数据.
int[] arrInt = new int[5];
> 定义时就指定初始值:(静态初始化)
静态初始化:定义数组时就指定数组元素的值。
元素类型[] 数组名 = new 元素类型[]{元素1,元素2,...};
例如:
int[] arr = new int[]{1,2,3,5};
2.一共有五个区域,分别是:
1> 栈区:stack
方法中定义的局部变量(和形参)都是在栈区:
栈区中的变量没有初始值,使用之前必须手动赋值!!
方法调用完毕,方法中定义的变量所占用的空间,就释放了!!
2> 堆区:heap
凡是new出来的对象都是在堆区!
Scanner s = new ...
int[] arr = new ...
ps:堆区中的变量都有初始值!!!
整型:0
浮点型:0.0
布尔型:false
引用数据类型:null
3> 方法区:method area
用来存放.class字节码文件和方法定义的区域 !
具体的说:
3. 以下每条语句执行时,内存中都发生了什么变化?
int[] arr = new int[4];
arr[3] = 10;
4.定义一个方法,参数是一个int数组.在方法中把所有的元素都打印出来.
1 import java.util.Scanner; 2 public class PractiseDemo{ 3 public static void main(String[] args){ 4 Scanner s = new Scanner(System.in); 5 System.out.print("请输入一个数字: "); 6 int x = s.nextInt(); 7 list(x); 8 } 9 public static void list(int value){ 10 int[] arr = new int[value]; 11 for(int i =0;i<=(value-1);i++ ){ 12 System.out.println(arr[i]); 13 } 14 } 15 }
1 /* 2 数组的遍历:traversal 3 依次访问数组中每个元素的机制: 4 5 如果程序中出现大量重复的代码,考虑优化: 6 目前优化有两种方式: 7 1.循环 8 2.封装成方法 9 10 11 */ 12 public class ArrayDemo5{ 13 public static void main(String[] args){ 14 int[] arr = {1,2,3,4,5,6,7,8,9,10}; 15 16 /* 17 System.out.println(arr[0]); 18 System.out.println(arr[1]); 19 System.out.println(arr[2]); 20 System.out.println(arr[3]); 21 System.out.println(arr[4]); 22 */ 23 24 //使用循环改进打印数组的元素 25 /* 26 for(int i = 0;i<5;i++){ 27 System.out.println(arr[i]); 28 } 29 */ 30 31 //数组的长度是我们查出来的,有可能数组是通过方法传递进来的. 32 //必须让程序自己计算数组的长度. 33 //数组有一个属性:length,代表的就是数组的长度(数组的元素的个数) 34 for(int i = 0;i<arr.length;i++){ 35 System.out.println(arr[i]); 36 } 37 38 } 39 }
1 /* 2 数组操作容易见到的两个问题: 3 1.数组索引越界异常:java.lang.ArrayIndexOutOfBoundsException: 4 0 length-1 5 -1 length+1 6 2.空指针异常:java.lang.NullPointerException 7 数组类型的变量,不再指向内存中的数组.而是指向null值. 8 此时用数组名[索引值] 就会出现空指针异常. 9 10 11 */ 12 public class ArrayDemo7{ 13 public static void main(String[] args){ 14 int[] arr = {1,2,3,5}; 15 16 // java.lang.ArrayIndexOutOfBoundsException: 17 //运行时异常,在编译阶段不检查越界异常!!!报错信息中会提示错误的索引值! 18 // System.out.println(arr[40]); 19 20 //空指针异常: 21 // arr = null; 22 // System.out.println(arr[0]);//java.lang.NullPointerException:空指针异常!运行时异常: 23 24 } 25 26 }
1 /* 2 定义一个方法,参数是一个int数组.在方法中把所有的元素都打印出来 3 */ 4 public class ArrayDemo6{ 5 public static void main(String[] args){ 6 //调用方法 7 int[] arr = {1,2,3,5,6}; 8 9 printArray(arr); 10 printArray2(arr); 11 } 12 //返回值类型:void 13 //形参列表:int[] arr 14 public static void printArray(int[] arr){ 15 // 16 for(int i = 0;i<arr.length;i++){ 17 System.out.println(arr[i]); 18 } 19 } 20 21 // 22 public static void printArray2(int[] arr){ 23 // 24 for(int i = 0;i<arr.length;i++){ 25 System.out.print(arr[i]); 26 //判断是否是最后一个元素:(索引值是长度值-1就说名是最后一个元素) 27 if(i != arr.length - 1){ 28 System.out.print(","); 29 } 30 } 31 } 32 33 34 }
/* 求最值的思路: 求最大值: 先定义一个变量,初始值是数组的第一个元素!! 然后从第二个元素开始遍历数组, 判断: 如果遇到了比变量大的值,让元素的值赋值给变量. 遍历完成后,整个数组的最大值就保存在变量中!! 求最小值: 先定义一个变量,初始值是数组的第一个元素!! 然后从第二个元素开始遍历数组, 判断: 如果遇到了比变量小的值,让元素的值赋值给变量. 遍历完成后,整个数组的最小值就保存在变量中!! */ public class ArrayDemo8{ public static void main(String[] args){ int[] arr = {9,5,2,70}; System.out.println("最大值是: " + getMax(arr)); } //获取最大值: //返回值类型:int //形参列表:int[] arr public static int getMax(int[] arr){ //遍历数组,获取最大值 int max = arr[0]; //从第二个元素开始遍历数组 for(int i = 1;i<arr.length;i++){ //判断 if(arr[i] > max){ max = arr[i]; } } // return max; } }