05_方法和数组

Day05笔记
课程内容
1、方法
2、数组
方法
方法的概述
1、概念:
     有些代码表示一个独立的功能,这个功能还经常使用,那么就把这段代码用大括号{}包起来,给这个代码起一个名字,将来只要写这个名字,就表示要调用这段代码。这段代码就是一个方法。
2、定义格式:
     修饰符 返回值类型 方法名称 (参数列表) {
          方法体语句;
          return语句;
}
3、相关概念的解释:
     1、修饰符:描述方法的权限、静态、抽象。当前阶段全部都是public static
     2、返回值类型:
          当前方法生产出来的数据的数据类型
     3、方法名称:
          将来用于表示这段代码,一旦写出了方法名称,就表示要执行这段代码
          第一个单词的首字母小写,从第二个单词开始,首字母大写
一般定义成一个动词或者动宾结构
     4、参数列表:
          表示这段代码在完成功能的过程中,需要获取的外界的资源
          在定义方法的时候,参数列表指的是:形式参数,只是表示一个不知道的数据
          声明参数的格式:数据类型1 变量名1, 数据类型2 变量名2
     5、方法体语句:
          真正要经常使用的代码,表示这段代码的真正功能和逻辑,表示真正完成这个功能        使用的代码
     6、return语句:
          这段代码最终生产出来的结果,结果数据的数据类型应该和返回值类型一致
          return也表示当前方法结束
4、调用格式:
     方法名称(实际参数);
5、方法调用内容解释:
     1、方法名称:
          不是定义方法,所以不需要写方法的返回值类型
     2、实际参数:
          真正确定方法中需要使用的资源,传入的是真正的数据(就一定是有初始化过的变        量或者是常量)
代码示例
class Demo01_方法定义 {
    public static void main(String[] args) {
        System.out.println("Hello World!");
        //盖饭 gf = 做饭(烂白菜, 镉大米, 地沟油);
        int a = 10;
        int b = 20;
        int sum = getSum(a, b);
        System.out.println(sum);
    }

    /*定义一个做饭的方法
    public static 盖饭 做饭(菜 c, 米 m, 油 y) {
        y热了
        c放入已经热了的y中
        对c进行搅拌
        把m蒸熟
        将熟了的c放到蒸熟的m上

        return cm;
    }
    */

    //定义求和的方法,可以计算两个数字的和
    //返回值类型:int,两个整数求和,结果还是一个整数
    //参数列表:int a, int b
    public static int getSum(int a, int b) {
        int sum = a + b;
        return sum;
    }
}
方法的注意事项
1、调用的注意事项:方法定义出来之后,不调用就不会执行
     单独调用:不对方法进行输出、也不使用一个变量来接收方法的返回值,只是单独的对方法进行调用。方法只是完成某些功能,没有什么具体产出。
     输出调用:有返回内容的方法,可以进行输出调用。在输出语句中,输出的内容是一个方法的调用。其实输出的是这个方法的返回值。(只能对返回内容输出一次)
     赋值调用:有返回内容的方法,可以使用一个变量,接收方法的返回值。可以对这个变量反复使用。
2、方法定义注意事项:
     1、方法不能嵌套定义,但是可以相互调用,甚至可以自己调用自己
     2、方法和方法都是平级关系
3、参数列表:
     1、形式参数:表示将来要使用的那个数据,但是现在不清楚数据具体内容,所以使用一个变量来表示。需要加上数据类型(其实是对变量的声明),变量和变量之间使用逗号进行分割。
     2、实际参数:表示在方法调用时,真正使用的那个数据。(本质是对变量的赋值和使用)。不需要加上数据类型,参数和参数之间使用逗号分割。
4、return语句:
     1、表示方法结束,用于表示方法返回内容
     2、如果方法有具体的返回内容,那么就必须有return语句,return后面就必须跟上一个具体的数据,这个数据的数据类型必须和方法声明中的返回值类型一致。
     3、如果方法没有具体的返回内容,那么就可以不写return语句,如果一定要写上return语句,可以写一个【return;】,用于表示方法结束。如果写的是return;或者是没写return语句,那么方法的返回值类型必须是void,表示没有任何返回内容
     4、返回值:一定是返回给方法的调用者。
代码示例
class Demo02_方法的注意事项 {
    public static void main(String[] args) {
        //直接调用
        printHL();
        //System.out.println(printHL());
        //输出调用
        System.out.println(getMax(10, 20));
        //赋值调用
        int max = getMax(10, 20);
        System.out.println(max);
    }

    //打印5次HelloWorld
    public static void printHL() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("HelloWorld");
        }
        return;
    }

    //两个数据获取较大值方法
    public static int getMax(int a, int b) {
        int max = a > b ? a : b;
        return max;
    }
    /*打印25次HelloWorld
    public static void print() {
        //编译报错,方法不能嵌套定义
        public static void print5() {
        
        }

        print5
    }
    */
}
练习1
定义一个方法,可以获取三个整数的最大值
键盘录入三个整数,调用方法,获取最大值
代码示例
import java.util.Scanner;
class Demo03_方法练习获取最值 {
    /*
    定义一个方法,可以获取三个整数的最大值
    键盘录入三个整数,调用方法,获取最大值
    */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        int z = sc.nextInt();
        int max = getMax(x, y, z);
        System.out.println("最大值为:" + max);
    }

    //获取三个整数最大值的方法,返回值类型int,参数列表int a, int b, int c
    public static int getMax(int a, int b, int c) {
        if (a > b && a > c) {
            return a;
        } else if ( b > a && b > c) {
            return b;
        } else {
            return c;
        }

        /*
        int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
        return max;
        */
    }
}
练习2
定义一个方法,判断两个整数是否相等
键盘录入两个整数,调用方法,判断是否相等
代码示例
import java.util.Scanner;
class Demo04_方法练习判断相等 {
    /*
    定义一个方法,判断两个整数是否相等
    键盘录入两个整数,调用方法,判断是否相等
    */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        boolean result = isEqual(x, y);
        System.out.println("这两个数字" + (result ? "" : "不") + "相等");
    }

    /*
        定义一个方法,判断两个整数是否相等
        返回值类型:boolean
        参数列表:int a, int b
    */
    public static boolean isEqual(int a, int b) {
        /*if (a == b) {
            return true;
        } else {
            return false;
        }

        return a == b ? true : false;*/

        return a == b;
    }
}
练习3
定义一个方法,可以打印指定行数和列数的星星矩形
键盘录入两个整数,分别表示行数和列数,调用方法,打印矩形
代码示例
import java.util.Scanner;
class Demo05_方法练习打印矩形 {
    /*
    定义一个方法,可以打印指定行数和列数的星星矩形
    键盘录入两个整数,分别表示行数和列数,调用方法,打印矩形
    */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int row = sc.nextInt();
        int col = sc.nextInt();
        printRect(row, col);
    }
    /*
        返回值类型:void,打印不是返回值
        参数列表:int row, int col
    */
    public static void printRect(int row, int col) {
        for (int i = 1; i <= row; i++) {
            //打印col个星星
            for(int j = 1; j <= col; j++) {
                System.out.print("*");
            }
            //加一个换行
            System.out.println();
        }
    }
}
方法在内存中的情况
Jvm虚拟机的内存划分
1、jvm是运行java代码的容器,需要分成一些不同的区域,不同的区域有不同的特殊作用。
2、区域的说明:
     1、栈内存:先进后出,对于方法先进后出。作用:执行方法的。【常用】
     2、堆内存:用于存储数据量较大的数据。比如数组、对象【常用】
     3、方法区:用于存储类的字节码对象,存储一些静态变量,存储常量【常用】
     4、本地方法区:和本地方法相关,在java代码中,有一些要和C语言代码交互的方法,称为本地方法,加上native关键字的就是本地方法。
     5、寄存器:和cpu有关,用于控制代码的执行流程,和程序计数器有关。
方法调用时内存描述
1、方法调用的步骤
     1、启动jvm虚拟机之后,默认调用main方法,就会在栈内存中,开辟一块空间,专门用于主方法中变量的声明和计算,形象的称为“方法进栈”,这个专门用于执行当前方法的区域,称为“栈帧”
     2、主方法中调用了其他的方法,在主方法不出栈的前提下,其他方法进栈,主方法将自己的一些数据传递给被调用的方法,被调用方法,执行完成之后,将结果返回给主方法,被调用的方法出栈
     3、继续执行主方法
2、图示:
     
方法的重载
1、没有方法重载的时候:
     很多方法,逻辑相似的,但是参数列表是不同的,就需要有很多的方法名称。
     调用者(程序员)需要记忆很多的方法名称,就非常不方便。
     希望逻辑相似的代码,参数不同的方法,可以使用相同的方法名称。
2、方法重载:
     定义:在同一个类中,方法名相同,参数列表不同,与返回值类型无关【记忆】
     名称:重载,overload,超载
3、注意事项:
     1、在同一个类中,不能是无关类、也不能是子父类,必须是同一个类
     2、方法名称相同:连大小写都必须一模一样
     3、参数列表不同:
          参数的数据类型不同
          参数的个数不同
          参数的数据类型的顺序不同
          【注意】参数的名称不同,不能认为成参数列表不同,而是参数列表相同
     4、与返回值类型无关:调用方法的时候,无法判断需要什么返回值类型,所以相同方法名称,相同的参数列表,不同的返回值类型,对于虚拟机而言,没有任何区别,无法区分到底应该调用哪个方法
代码示例
class Demo06_方法的重载 {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 30;
        /*System.out.println(getSum2(a, b));
        System.out.println(getSumD2(12.34, 43.21));
        */
        System.out.println(getSum(a, b));
        System.out.println(getSum(1, 2, 3));
        System.out.println(getSum(12.34, 43.21));
        
        System.out.println(getSum(1, 2.0));
        System.out.println(getSum(1.0, 2));


    }
    /*
    public static double getSum(int a, int b) {
        return a + b;
    }

    定义方法,计算int和double的和
    public static double getSum(int i, double d) {
        return i + d;
    }*/

    //定义方法,计算int和double的和
    public static double getSum(int a, double b) {
        System.out.println("int + double 被调用了");
        return a + b;
    }

    //定义方法,计算double和int的和
    public static double getSum(double a, int b) {
        System.out.println("double + int 被调用了");
        return a + b;
    }

    //定义方法,计算两个int的和
    public static int getSum(int a, int b) {
        return a + b;
    }
    //定义方法,计算三个int类型的和
    public static int getSum(int a, int b, int c) {
        return a + b + c;
    }
    //定义方法,计算两个double的和
    public static double getSum(double a, double b) {
        return a + b;
    }

    /*
    //定义一个方法,计算两个int类型数据的和
    public static int getSum2(int a, int b) {
        return a + b;
    }

    //定义一个方法,计算三个int类型数据的和
    public static int getSum3(int a, int b, int c) {
        return a + b + c;
    }

    //定义一个方法,计算两个double类型数据的和
    public static double getSumD2(double a, double b) {
        return a + b;
    }
    */
}
数组
数组的概述
1、数组:用于存储相同数据类型的数据的,容器
2、使用数组的原因:
     如果没有数组,所有的变量都需要使用变量名称,变量名称过多的时候,就不方便操作,变量和变量之间,没有关系,没有固定的规律。
     数组的解决方案:只需要有一个容器的名称,容器中每个位置都有自己的序号,元素存储进来之后,就可以通过【容器名称 + 元素序号】来获取和修改这个位置的元素。本质:就是通过有规律的序号,访问没有规律的元素内容。
3、数组的定义方式:
     元素的数据类型[] 数组名称 = new 元素的数据类型[数组的大小];
4、数组的定义解释:
     元素的数据类型:在数组中有数据,就称为元素,数据的类型就是元素类型
     []:表示当前数组是一个一维数组
     数组的名称:数组本身也是一个变量,有自己的变量名称
     =:赋值符号,将=后面创建出来的数组的地址,赋值给=前面的变量
     new:在堆内存中开辟一块存储空间
     数组的大小:数组是一个容器,有存储的空间,能存储多少数据,数组的大小就是多少
5、打印内容的解释:[I@15db9742
     1、[:表示一个一维数组
     2、I:表示数组中存储的数据类型是int
     3、@:表示一个普通的分隔符
     4、15db9742:数组有一个内存地址,通过hashCode方法,将内存地址计算成一个数字,称为哈希码值,转成十六进制,15db9742
     说明:简称这个打印的内容为:数组的内存地址
代码示例
class Demo07_数组的定义 {
    public static void main(String[] args) {
        //定义一个int类型的数组
        int[] arr = new int[3];
        System.out.println(arr);
    }
}
数组的初始化
1、初始化:给数组的数据分配内存空间,并且给元素赋值
2、分类:动态初始化、静态初始化
3、动态初始化:
     元素的数据类型[] 数组名称 = new 元素的数据类型[数组中元素的个数]
     数组中的元素赋值:
          数组名称[元素的索引] = 元素值;
     注意事项:
           1、所有的元素,都需要使用这个格式来一一赋值
          2、元素的索引:从0开始,到元素个数-1结束
          3、如果没有给元素赋值,那么数组的元素有一个默认的初始化值,0
4、静态初始化:
     元素的数据类型[] 数组名称 = new 元素的数据类型[]{元素值的罗列}
     注意事项:
          1、在后面的方括号中,不要写任何元素个数
          2、元素值的罗列,使用逗号分割
          3、罗列的元素,数据类型必须和声明中的元素数据类型一致
          4、静态初始化有一个简写的格式【常用】
               元素的数据类型[] 数组名称 = {元素值的罗列};
               这种写法,不能将数组的声明和数组的赋值分离开
代码示例1
class Demo08_数组的动态初始化 {
    public static void main(String[] args) {
        int[] arr = new int[3];
        //默认的初始化值
        System.out.println(arr[0] + "..." + arr[1] + "..." + arr[2]);
        arr[0] = 10;
        arr[1] = 20;
        arr[2] = 30;
        System.out.println(arr[0] + "..." + arr[1] + "..." + arr[2]);
    }
}
代码示例2
class Demo09_静态初始化 {
    public static void main(String[] args) {
        int[] arr = new int[]{10, 20, 30};
        System.out.println(arr[0] + "..." + arr[1] + "..." + arr[2]);
        //编译报错,不能在静态初始化格式中,参与动态初始化的格式
        //int[] arr2 = new int[3]{10, 20, 30};
        //编译报错,后面的元素值,和声明不符
        //int[] arr3 = new int[]{12.34, 23.45, 43.21};

        int[] arr4 = {100, 200, 300};
        System.out.println(arr4[0] + "..." + arr4[1] + "..." + arr4[2]);


        int[] arr5;
        arr5 = new int[]{11, 22, 33};

        int[] arr6;
        arr6 = {666, 888};
    }
}
数组在内存中的理解
一个数组的内存图
1、创建数组在内存中的过程:
     1、在栈内存中声明一个引用,将来存储数组的地址
     2、在堆内存中开辟一块空间,存储元素
     3、给数组中的元素进行默认的初始化赋值,都变成了0
     4、将堆内存中的数组的地址,赋值给栈内存中的引用
2、图示:
   
3、代码示例
class Demo10_一个数组的内存图 {
    public static void main(String[] args) {
        int[] arr = new int[3];
        System.out.println(arr[1]);
        arr[1] = 666;
        System.out.println(arr[1]);
    }
}
两个数组的内存图
1、说明:
     只要碰到了new关键字,一定是要在堆内存中开辟一块新的空间
2、图示:
   
3、代码示例
class Demo11_两个数组的内存图 {
    public static void main(String[] args) {
        int[] arr1 = new int[3];
        arr1[1] = 666;
        int[] arr2 = new int[3];
        arr2[1] = 888;
        System.out.println(arr1[1] + "..." + arr2[1]);
    }
}
两个引用指向同一个数组
1、说明:
     两个引用中记录的是同一个数组的地址
     通过任意一个引用操作了数组中的内容,将来通过另一个引用找到数组之后,都是改变过的情况
2、图示:
   
3、代码示例
class Demo12_两个引用指向同一个数组 {
    public static void main(String[] args) {
        int[] arr1 = new int[3];
        arr1[1] = 666;
        int[] arr2 = arr1;
        arr2[1] = 888;
        System.out.println(arr1[1] + "..." + arr2[1]);
    }
}
数组的异常
异常
1、例外情况:代码中,程序中,出现了和生活中不太相符的情况,就是例外情况,将这种情况封装成一个对象,称为“异常对象”。有了异常之后,就可以结束程序或者跳转程序。
2、在数组操作过程中,经常出现的两个异常:
     数组索引越界异常
     空指针异常
数组索引越界异常
1、Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
     异常   在  线程  主          数组索引 超过了边界   异常:数组索引越界异常
2、原因:访问了数组中不存在的索引
3、避免:不要访问数组中不存在的索引
class Demo13_数组索引越界异常 {
    public static void main(String[] args) {
        int[] arr = {11, 33, 55};
        arr[0] = 666;
        arr[1] = 888;
        arr[2] = 999;
        arr[3] = -666;
    }
}
空指针异常
1、Exception in thread "main" java.lang.NullPointerException
     异常   在  线程  主             空   指针  异常:空指针异常
2、原因:
     栈内存中的引用,为空,不再指向任何堆内存中的数据,但仍然要强行访问堆内存中的数据。
3、指针:是C语言中的概念,指针类型的变量,存储的不是具体的数据,而是指的数据的地址。在java中已经不能直接操作内存地址,该这个指针类型为【引用类型】。空指针异常,其实就是空引用异常,都是表示无法获取数据的地址。
4、避免:在操作任何一个引用之前,可以先判断这个引用是否为null,如果为null,就不进行操作。
class Demo14_空指针异常 {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33};
        System.out.println(arr[0] + "..." + arr[1] + "..." + arr[2]);
        arr = null;
        if (arr != null) {
            System.out.println(arr[0] + "..." + arr[1] + "..." + arr[2]);
        }
    }
}
数组的操作
数组的遍历
1、遍历:把数组中的每个元素都获取出来,对每个元素进行输出
2、方法:获取到所有的元素的索引,根据索引获取到元素
3、索引范围:0~元素的个数-1
4、获取元素个数:数组名称.length
class Demo15_数组的遍历 {
    public static void main(String[] args) {
        int[] arr = {11, 33, 55, 22, -66};
        //遍历这个数组,获取所有的索引
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}
数组获取最值
1、数组中有若干元素,获取数组的最大值
2、声明一个最大值变量
数组的反转
1、数组中有若干元素,将第一个元素和最后一个元素交换,第二个元素和倒数第二个元素交换
数组的查找
1、数组中有若干元素,找到某个指定值,在数组中的索引

猜你喜欢

转载自www.cnblogs.com/man-tou/p/10635884.html
今日推荐