张小飞的Java之路——第六章

文章通过一个故事形式介绍了编程中的关键概念,包括方法的概念(如代码复用、定义、返回值、重载),主方法main的特殊性,数组的定义、使用、遍历、求和以及常见错误,还有二分查找算法和用户输入的处理。强调了方法在提高代码效率中的重要性和数组在处理多数据时的便利性。
摘要由CSDN通过智能技术生成

写在前面:

视频是什么东西,有看文档精彩吗?

视频是什么东西,有看文档速度快吗?

视频是什么东西,有看文档效率高吗?



清晨 06:16,张小飞睡的正香,突然感觉到一股寒意 ,或许是因为第六感的缘故,张小飞警觉的张眸

果然,还迷糊的眼睛,看到了一个人影。张小飞下意识的想要大叫‘好汉饶命,我上有老父,下有妻儿,家穷……’之类的话

而后,这个床边的人毫不犹豫的用手捂住了张小飞的嘴。便听一个熟悉的声音道:“嘘,是我”

卧……卧槽……

张小飞怒了,不怕贼偷就怕贼惦记啊,这家伙绝对是属贼的,好好的人不做,你做梁上君子?

诸小亮:“行了,起床了,看看这都几点了,你老是睡过”

其实知道这人是诸小亮后,张小飞已经不紧张了,不过还是很生气,说到:“那你也不能这样啊,不知道人吓人,吓死人啊,不会敲门吗?”

“敲门?我整整敲了10分钟的们,你都没听见,这不是没办法吗?”

“其实…,我听见了”

“听见了,你还不起来开门?”

“我梦里正在吃火锅,隔壁装修,咚咚咚,烦死了,就没管”

“…”

4. 方法

十分钟后。

诸小亮:“今天咱们学习一个新的东西:方法

张小飞:“这是个什么东西?”

诸小亮:“简单来说:是一段具有特定功能的代码

“。。。。。。,不懂”

1. 定义

诸小亮:“没关系,先看看它的定义”

修饰符 返回值类型 方法名(参数类型 参数名称1,参数类型 参数名称2...)
{
    执行语句;
    return 返回值;
}

“你这…,搞得,更看不懂了,什么修饰符、返回值的”

诸小亮:“不要急,会慢慢跟你说的”

2. 为什么需要方法?

诸小亮:“先给你一个需求:打印 * 号,每行打印 5 个 * 号,打印 5 行”

张小飞:“这个太简单了”

public static void main(String[] args){
    System.out.print("*****");
    System.out.print("*****");
    System.out.print("*****");
    System.out.print("*****");
    System.out.print("*****");
}

诸小亮:“额…,其实我是想让你用 for 循环去实现”

“那不是昨天讲的东西吗?”

“是啊,怎么了?”

“我这个人,从来不回头看过去的事”张小飞说到

诸小亮:“滚蛋,别废话,赶紧用 for 在来一遍”

张小飞:“…,好吧,好吧,满足你”

public static void main(String[] args){
    for(int i = 0;i<5;i++){
        for(int j = 0;j<5;j++){	
            System.out.print("*");
        }
        System.out.println();
    }
}

“嗯,不错,如果再给你一个需求:还是打印 * 号,每行打印 3 个 * 号,打印 3 行,你怎么做?”

“…”张小飞像看白痴一样的看着诸小亮“这就更简单了,复制上面代码,改一下不就行了?”

public static void main(String[] args){
    //需求1:打印 * 号,每行打印 5 个 * 号,打印 5 行
    for(int i = 0;i<5;i++){
        for(int j = 0;j<5;j++){	
            System.out.print("*");
        }
        System.out.println();
    }

    //需求2:打印 * 号,每行打印 3 个 * 号,打印 3 行
    for(int i = 0;i<3;i++){
        for(int j = 0;j<3;j++){	
            System.out.print("*");
        }
        System.out.println();
    }
}

诸小亮:“咱们来分析一下这两段代码,功能差不多,都是打印 * 号”

张小飞:“确实是这样,但一个是打印 5 行,一个是 3 行,这也不算问题啊”

“如果给你 N 个这样类似的需求呢?你难道要把复制 N 遍?”

“额…,我明白你的意思,你是想说它们很类似,却不能重复使用对吧?”

“是的,这种方式的问题是代码的复用率极其低下,使用 ‘方法’可以这个问题,比如:”

/**
 * 既然功能一样,代码也差不多,就写一个方法专门用来打印 * 号, 用来提高代码的复用性
 *
 * 定义一个方法:专门用来打印*号,这样如果有类似的需求,直接调用这个方法就行
 *
 * 另外这个方法需要两个参数:
 * 	row 表示要打印几行
 * 	column 表示每行打印多少个 * 号
 */
public static void print(int row, int column){
    for(int i = 0;i < row;i++){
        for(int j =0;j< column;j++){
            System.out.print("*");
        }
        System.out.println();
    }
}

public static void main(String[] args){
    //需求1:每行打印 5 个 * 号,打印 5 行
    print(5, 5);//调用自定义的方法,(5, 5)相当于设置它的两个参数:row=5,column=5

    System.out.println("----------华丽的分割线-----------");

    //需求2:每行打印 3 个 * 号,打印 3 行
    print(3, 3);
}

结果:

在这里插入图片描述
“上面的代码,你能看懂吗?”

“大概可以看懂,不过还是得麻烦您解释一下”张小飞说到

“这是自然,不过有些东西现在确实接触不到,会到以后再说”

1. public 和 static 是修饰符(Java中的关键字),以后再说
2. void:表示这个方法没有返回值,有些方法是有返回值的,稍后详述
3. print:**自定义的方法名,要符合标识符的规则,同时也要有意义,别用一些aa,bb,cc**
4. int row:**参数类型 和 参数名称(自定义),多个参数之间用"," 分隔**

“。。。,师兄,您这不行啊,一共 4 条,就解释了 2 条”

“没办法,先这样用吧,前两条后面会介绍的,其实这里最重要的是要记住:”

方法的作用:提高代码的复用性

3. main 方法

张小飞:“我们用的这个 main 也是一个方法吧,但是这个参数???”

image.png

诸小亮:“没错,但是 main方法比较特殊,被称为主方法,是 Java 程序的入口,执行 java 命令后,会首先进入 main 方法,同时也可以传递参数,比如(代码中会对参数解释):”

class Demo{
	public static void main(String[] args){
		System.out.println("main方法的参数是:");
        //打印 args 参数,args是字符串数组,还没学
		for(int i =0;i<args.length;i++){
			System.out.println(args[i]);
		}
	}
}

结果:

在这里插入图片描述

张小飞:“我是想问 String[] args 这个参数是什么意思”

诸小亮:“这个是数组,讲完方法,我们就会说到数组了,再等一会儿”

4. return

张小飞:“对了,在说方法定义的时候,还有一个 return 的东西,这是做什么的?”

诸小亮:“return:表示方法的结束,方法中必须有这个东西,格式:return 返回值;

“不对吧,上面定义的 print 方法中就没有 return”

“因为:print 方法的返回值是 void,**如果一个方法返回值类型是void,那么 return 可以省略,**当然即使是 void ,也可以写上 return,比如:”

在这里插入图片描述

“原来是这样,如果返回值不是 void 呢?”

“来,看看下面的这个 num 方法,你就明白了”

/**
* 该方法用来计算一个数跟 2 的乘积,并返回计算后的结果
*/
public static int sum(int a){
    int result = a * 2;
    return result;//该方法有具体的返回值类型,所以 return 不可少
}

public static void main(String[] args){
    // 调用有返回值的方法,既然有返回值,就需要对应的变量去接收
    int result = sum(10);
    System.out.println(result);
}

结果:

在这里插入图片描述

“明白了,我也来试一试”张小飞说到

5. 重载

诸小亮:“接着我们介绍方法中最后一个知识点:重载”

重载:是一种现象,具体表现:多个方法的名称一样,但是 参数类型 或 参数个数 不同

“师弟,这个概念一定要记住”

“明白,不过这个重载能不能给个例子?”

“这个简单,看下面代码:”

//该方法用来计算两个整数的和
public static int sum(int a, int b){
    return a + b;
}

//该方法用来计算两个小数的和
public static double sum(double a, double b){
    return a + b;
}

“师兄,上面代码有两个方法,但是参数类型和返回值不同,这就是:方法重载?”

“是的,不过方法的重载跟返回值无关,只需要关注:参数类型 和 参数个数

“哦,那么重载具体是有什么作用呢?”

“没有什么特别大的作用,其实就是告诉你:方法名可以重复

“。。。。。。”

“最大的作用:当方法的功能都一样,只参数不同时,没有必要起新的名称,用同一个名称即可,比如:”

//常用的print方法,就有很多重载形式
public void print(boolean b)
public void print(char ch)
public void print(int i)
public void print(double x)

“好吧,原来就这么点儿用处”

5. 数组

诸小亮:“接下来我们就开始学习:数组”

张小飞:“什么是数组呢?”

“数组—就是:一组数”

“。。。。。,这有什么用?”

1. 引入

诸小亮:“先看一下,之前我们写的求和方法:”

在这里插入图片描述

张小飞:“这个方法有什么问题嘛?”

“这是我写的,怎么可能有问题,不过上面是对两个整数的求和,如果需要对 3 个正数的求和呢?”

“这简单,仿照上面的方法,写一个重载方法不就行了?”张小飞说到

public static int sum(int a, int b, int c){
    return a + b + c;
}

“那如果需要对100、1000个数字求和呢?你还能用重载方法吗?”

“这——,您的意思是,用数组?”

“没错,通过数组可以解决这种多参数的问题”

2. 定义

诸小亮:“先了解一下数组的定义:”

  • 数组:一组数据的意思,是同一种类型的数据集合,一般称数组中的数据为:元素
  • 定义:元素类型[] 变量名 = new 元素类型[元素个数]

示例:

public static void main(String[] args){
    int[] arr = new int[3];// 定义一个 int 类型的数组,长度是3(表示能存放3个int类型的数字)
}

张小飞:“那具体怎么使用呢?”

数组中的数据默认都有编号(从0开始,也叫索引、下标),利用编号能方便的操作数据,比如:”

在这里插入图片描述

结果:

在这里插入图片描述

“师兄,你刚才只是定义数组,还没往里面存数据吧,怎么就有值了?”

“是的,不过创建数组时都会设置默认值,不同类型的数组,默认值也不同”

int、long、short--------0
double---0.0
boolean--false

“那么如何才能往数组中添加数据呢?”

“设置数据也是通过编号,比如:”

在这里插入图片描述

结果:

在这里插入图片描述

“原来是这样,那么设置其他元素就是 a[1]=10; arr[2]=11 这样的?”

“是的,你自己尝试一下吧”

3. 常见错误

张小飞:“这里出问题了,您来看一下”
image.png

image.png
诸小亮:“这是数组中一个常见的错误,原因是:尝试获取不存在的数据”

ArrayIndexOutOfBoundsException(数组下标越界),因为想获取不存在的下标

“不存在?不会啊,不是一个三个数么,怎么会不存在?”

“是这样的:数组中的元素从 0 开始编号,存 3 个元素的数组,它里面最大的编号是 2

“原来是这样,我明白了”

“另外,还需注意一点:不要操作空数组

“空数组?”张小飞问到

“空:表示没有任何东西,下面就是空数组:”

在这里插入图片描述

“上面代码,运行后会提示:**NullPointerException(空指针异常),**比如:”

image.png
“好的,好的,又学到了”

4. 另一种方式

诸小亮:“其实定义数组还有另外一种方式,在创建数组时,直接指定数组中的内容
示例:

public static void main(String[] args) throws IOException {
    
    //创建数组时,直接指定数组中的内容,格式:元素类型[] 变量名 = new 元素类型[]{元素1,元素2......}
    int[] arr = new int[]{1,2,3};
    System.out.println(arr[0])
}

张小飞:“嗯嗯,这样子确实方便不少”

“还有更方便的:”

在这里插入图片描述

“不过这种方式很少使用,了解一下就行” 诸小亮补充道

5. 遍历数组

张小飞:“遍历数组是什么意思?”

诸小亮:“其实就是用 for 获取数组中的每个元素?”

“for循环?要怎么实现?”

“数组有个 length 属性,表示数组的长度,用它就可以遍历数组,比如:”

public static void main(String[] args) throws IOException {
    int[] arr = {1,2,3};
    //遍历数组,数组中有几个元素length的值就是几
    for(int i = 0; i<arr.length; i++){
        System.out.println(arr[i]);
    }
}

结果:

在这里插入图片描述

张小飞:“原来是这样”

6. 求和练习

诸小亮:“好了,既然知道如何遍历数组,我们就写个方法,尝试对数组中的数据进行求和”

张小飞:“这就让我来吧”

//该方法,计算一组整数的和
public static int sum(int[] arr){
    int sum = 0;
    for(int i =0; i<arr.length; i++){
        sum = sum + arr[i];
    }
    return sum;
}

public static void main(String[] args){
    //求3个数的和
    int[] arr = {1,2,3};
    int res = sum(arr);
    System.out.println(res);//6
    
    //求6个数的和
    int[] arr2 = {1,2,3,3,4,6};
    int res2 = sum(arr2);
    System.out.println(res2);//19
}


诸小亮:“嗯,不错,不错”

7. 最值问题

诸小亮:“下面咱么说说最值问题”

张小飞:“什么是最值问题?”

“就是给你一个数组,然后获取它的最大值,比如:{1,2,3,3,4,6} ”

“这还不简单,6”

“。。。。不是让你用眼看,而是用代码写,如果给你 1000 个数字,你也用眼看吗?”

“哦哦,用代码…,怎么写?”


“首先,我们分析一下这个需求:因为是一组数,所以考虑使用数组 ”

“嗯嗯,1000个数肯定得用数组”张小飞说到

“接着,先拿前 2 个数比较,得出一个比较大的值(num)

“然后呢?”

“然后,用 num 跟第三个数字比较,又能得出一个比较大的值。。。。。。依次类推。”

“我明白了,就这样将数组中的元素都比较一遍,就能得出最大值”

“你说的没错,其代码:”

public static void main(String[] args) throws IOException {
    //求 arr 中的最大值
    int[] arr = {1,2,3,3,4,6};

    //1. max用来记录最大值,这里是先假设第一个数是最大值
    int max = arr[0];

    for(int i = 1;i<arr.length;i++){
        //2. 循环数据中的元素,每一个都跟 max 比较
        if(arr[i] > max){
            //3. 如果元素大于max, 记录这个数
            max = arr[i];
        }
    }
    System.out.println(max);//最终输出:6
}

“很简答啊” 张小飞说到

“不错,不过这个只是为数组排序打打基础”

8. 排序

张小飞:“排序,是对数组中的数组进行排序吗?”

诸小亮:“是的,对数组的元素进行排序,这是很常见的一种需求”

张小飞:“既然都能计算出最大值了,那么排序当然没有问题”

“哦?那你来试试,对一组数从小到大排序,比如:[3, 2, 5, 8, 1]”

“好啊,给我 5 分钟”

“不用着急写代码,先告诉我你的思路是什么?”诸小亮急忙拦着

“思路是这样的:”

  • 从小到大排,那么最后一个元素就是最大值
    • 第一步:数组中的 arr[0] 跟 arr[1] 比较,3>2,交换它俩的位置,结果:[2, 3, 5, 8, 1]
    • 第二步:arr[1] 跟 arr[2] 比较。。。。。。,以此类推
    • 最后第 arr[3] 跟第 arr[4] 比较,8 >1,所以它俩交换,结果:[2, 3, 5, 1, 8]

诸小亮:“嗯,不错,不过你这样仅仅是把最大值 8 放到了正确的位置上,其他的还是乱序”

张小飞:“还没说完呢,上面只是第一轮比较,计算出最大值并放到最右边”

  • 接下来进行第二轮比较,把第 2 大的值放到下标为 [3] 的位置。。。。。。,以此类推

“没错,其实你的这种方式称为:冒泡排序,每一轮都比较出一个最大值放到指定位置


诸小亮:“既然这样,你就写一下代码吧”

张小飞:“没问题,稍等一下”

五分钟后。

张小飞:“代码已经写好了”

public static void main(String[] args) throws IOException {
    //需要排序的数组
    int[] arr = {3,2,5,8,1};

    //1. 外层for循环:控制一共比较几轮
    for (int i = 1; i < arr.length; i++) {

        //2. 内存for循环:找出每一轮的最大值,并放到指定位置
        for (int j = 0; j < arr.length - i; j++) {
            //2.1 相邻元素相互比较,如果左边元素大, 就交换位置
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        
        //3. 每一轮比较结束后,遍历数组
        for(int k = 0; k<arr.length; k++){
            System.out.print(arr[k]+",");
        }
        System.out.println();
    }
}

结果:
image.png

9. 二分查找

诸小亮:“小时候,你有没有玩过一种猜数字的游戏?”

张小飞:“猜数字?什么游戏?”

“你心里先1-100之中的一个数字,我来猜,每猜测一次,你要告诉我(大了、小了、相等)”

“哦~~,这种游戏啊,当然玩儿过,如果你猜50,我说大了,那么数字一定在1-49之中,对不对?”

“是的,一下缩小一半范围,这种专业说法是:二分查找,也叫:折半查找

“哦哦,怎么突然之间说起这个了?”

“我希望你能在 [1,2,3,12,24,25,33,62,99] ,这个有序数组中找到,数字 12 的下标是多少”

“这还不简单,下标就是…1,2,3…,哦,不对,应该是0,1,2…,找到了, 12 的下标是 3”

“。。。。。,不是让你一个个数,而是用 二分查找 的方式” 诸小亮说到

“这样啊,你不早说”张小飞不满的白了诸小亮一眼

“好好好,是我不对,没有说清楚,现在再说说你的思路吧” 诸小亮无奈道

“让我想想,利用二分查找,要查的数是 12…,我想到了:”

  • 先根据 起始坐标0 和 最大坐标8 计算出中间元素的下标4,进而拿到对应的值 arr[4]
    • 如果 arr[4] > 12 ,那么 12 就在,下标为 0 - 3 之间
    • 如果 arr[4] < 12 ,那么 12 就在,下标为 5 - 8之间
  • 上面数组 arr[4] = 24,表示 12 在下标为 0 - 3 之间
  • 接下来,计算 0 - 3 的中间元素下标。。。。。以此类推

诸小亮:“你说的不错,不过如果给你的数字在数组中就不存在呢?比如:6”

张小飞:“不存在?按照上面的思路:”

  • 第一次:arr[4] > 6,那么 6 就在,下标为 0 - 3 之间
  • 第二次:arr[1] < 6,那么 6 就在,下标为 2 - 3 之间
  • 第三次:arr[2] < 6,那么 6 就在,下标为 3 - 3 之间

张小飞:“这时候 起始坐标 和 最大坐标 的值一样了,没办法再次查找了,也就不能循环了

诸小亮:“完全正确,那么你能用代码把你这个思路写出来吗?”

张小飞:“嗯…,我尽量试试吧”

//该方法:用于查找 num 在 arr 中的下标
public static int binarySearch(int[] arr, int num){
    int max = arr.length-1;//最大下标
    int min = 0;//最小下标
    int mid;//中间元素下标


    //当 最小下标 >= 最大下标时,循环结束,说明数组中没有对应的数字
    while(min >= max){

        //1. 计算中间下标
        mid =  (max + min) / 2;

        //2. 如果 arr[mid] > num,那么它一定在 min ~ (mid-1) 之间
        if(arr[mid] > num){
            max = mid - 1;
        }else if(arr[mid] < num){//3. 如果 arr[mid] < num,那么它一定在 (mid+1) ~ max 之间
            min = mid + 1;
        }else {
            return mid;//4. 如果 arr[mid] == num,直接返回 mid
        }
            
    }
    
    return -1;//-1表示num不再arr数组中
}

public static void main(String[] args){
    int[] arr = {1,2,3,12,24,25,33,62,99};
    int res = binarySearch(arr, 62);
    System.out.println(res);
    
}


结果:

image.png

10. 二维数组(了解)

张小飞:“师兄,这个二维数组是???”

诸小亮:“二维数组:其实就是多个一维数组,上面介绍的都是一维数组,比如:”

在这里插入图片描述

在这里插入图片描述


“哦,是这样,那二维数组应该怎么用呢?”

“也很简单,它的定义:数据类型[][] 变量名 = new 数据类型[3][4];

image.png

“上图:定义了一个 3 行 4 列的二维数组,其实就是3个一维数组,每个一维数组中可以存 4 个 int 数字”

张小飞:“那,是这样获取数组中的数据吗?”

在这里插入图片描述

诸小亮:“是的,上图表示:获取第 1 个一维数组中的第 2 个元素”

诸小亮:“另外,还有第二种定义方式:”

在这里插入图片描述

“这个就有些看不懂了” 张小飞说到

“其实就是定义了一个有 3 个一维数组的二维数组:”

第一个一维数组:{1,2,3}
第二个一维数组:{4,5,6}
第三个一维数组:{7,8,9}

“原来如此”

6. 用户输入

诸小亮:“下面我们介绍一个特殊的知识,获取‘用户输入’”

张小飞:“‘用户输入’?,要怎么输入?又怎么获取?”

1. 处理用户输入

诸小亮:“在运行 Java 程序时,使用 Scanner 可以接收用户的输入,比如: ”

// import还未讲,先使用
import java.io.*;
import java.util.Scanner;

class Demo{
	public static void main(String[] args) throws IOException {
		System.out.println("请输入:");
        Scanner sc = new Scanner(System.in);
        // nextLine:获取用户输入的一行数据,
        String s = sc.nextLine();//当程序执行到 sc.nextLine() 时,会等待用户输入,用户输入后按回车代码才接着执行
        System.out.println("您输入的是:" + s );
        sc.close();
    }
}

张小飞:“这段代码中,有很多东西都没有见过啊”

“我先给你解释一下:”

  • 最上面的 import 还未讲到,我们先用
  • Scanner :是 Java 提供的用来处理用户输入的一个工具
  • nextLine是一个方法:当执行这句代码时候,程序会等待我们输入,输入后按回车代码才接着执行

“那,在哪里输入东西呢?”张小飞问到

“在命令行,先把程序跑起来,你来看看”
111.gif
“有意思,有意思,我也来试一试”

2. 求和

诸小亮:“既然可以接收用户输入,那么就来个需求:根据用户输入的两个数字,求它们的和?”

张小飞:“师兄,您要求输入两个数字,上面演示的只是接收用户输入的一句话,这个…”

“不好意思,是我的疏忽,那就我来吧,其实接收用户输入的数字用 nextInt() 就行了,比如:”

public static void main(String[] args) throws IOException {
    System.out.println("请输入两个数字:");
    Scanner sc = new Scanner(System.in);
    //nextInt:获取用户输入的数字,多个数字之间使用空格隔开
    int num1 = sc.nextInt();//获取第一个数字
    int num2 = sc.nextInt();//获取第二个数字
    System.out.println("和是:" + (num1 + num2));
    sc.close();
}

结果:
111.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值