• day05-Java方法和数组


    今天主要学习如下内容:
      1.方法定义,方法调用,方法重载等内容
      2. 数组相关内容,以及有数组初始化引出的
      3. Jvm的运行时数据区的内存模型相关知识

    一、方法

    • 引入:

        文件上传是做一个电商网站所必不可少的功能,比如每一个商品都需要上传若干商品图片,网站上各种品牌都需要上传其logo,用户在注册时可以上传头像…

      假设你现在已经写了100行代码完成了文件上传功能,但问题是网站的很多地方都要使用这一功能,比如管理商品数据的商品服务,管理用户数据的用户信息服务等等。

      问题来了,这些地方都要使用文件上传的功能,怎么办呢?

        方案1

          在每个用到文件上传功能的地方重写这些100行代码 但是方案1会引发一系列的问题!!

        方案2

          复用这100行代码,将这些代码放在一个{}中,并给它们起个名字,通过名字来复用这段代码

      方法定义:方法就是完成特定功能的代码块(在有些其他语 言中,也被成为函数)

    • 方法定义的格式:

    修饰符 方法返回值类型 方法名(参数1类型 参数1名称, 参数2类型 参数2名称, ……) {

    方法体语句;

    return 返回值;

    }

    方法定义的格式说明:

      修饰符:现在先认为是固定的 public static

    返回值类型:方法体中的代码执行结果的数据类型

    方法名 :标识符

    参数 :类比数学中函数的自变量 z = f(x, y)

    方法体:实现具体功能的语句结合

    return:跳转控制关键字

    返回值:方法执行的到的最终结果 注意: return 返回值;这句并非必须

    如何写一个方法呢?

    两个明确 :

      1. 返回值类型----- 明确功能结果的数据类型
      2. 参数列表   --- -- 明确有几个参数,以及参数的类型

    学习了方法的定义之后,如何使用方法,完成特定的功能呢? 此时,我们就需要学习,方法调用了。 对于方法的调用,又分了两种情况:

    • 有返回值的方法调用
    • 没有返回值的方法调用

    方法调用注意事项:

      1. 方法不调用不执行
      2. 方法与方法是平级关系,不能嵌套定义
      3. 方法定义的时候参数之间用逗号隔开
      4. 方法调用的时候不用再传递数据类型
      5. 如果方法有明确的返回值,一定要有return带回一个值

                                                                         图:一次方法调用的过程  

    /**
     *  方法定义:方法就是完成特定功能的代码块(在有些其他语 言中,也被成为函数function)
    
        方法定义的格式
    
        修饰符  方法返回值类型 方法名(参数1类型 参数1名称,参数2类型 参数2名称, ……) {
            方法体语句;
            return 返回值;
        }
    
        方法定义的格式说明:
        修饰符:现在先认为是固定的 public static
        返回值类型:方法体中的代码执行结果的数据类型
        方法名 :标识符
        参数 :类比数学中函数的自变量 z = f(x, y)
        方法体:实现具体功能的语句结合
        return:跳转控制关键字
        返回值:方法执行的到的最终结果
    
        定义方法:两数求和(int)
    
        如何写一个方法呢?两个明确
        返回值类型 明确功能结果的数据类型
        参数列表 明确有几个参数,以及参数的类型
    
        对于方法的调用,又分了两种情况:
        1.有返回值的方法调用
        2.没有返回值的方法调用
    
        方法调用注意事项:
        1.方法不调用不执行
        2.方法与方法是平级关系,不能嵌套定义
        3.方法定义的时候参数之间用逗号隔开
        4.方法调用的时候不用在传递数据类型
        5.如果方法有明确的返回值,一定要有return带回一个值
     *
     *
     */
    public class MethodDemo1 {
    
      public static void main(String[] args) {
        //用变量接收有返回值的方法调用
        int result = add(3, 4);
        System.out.println(result);
    
        //输出调用
        System.out.println(add(3,4));
    
        //直接调用 有返回值的方法调用没有意义
        add( 3, 4);
    
        //调用方法没有返回值的方法, 只能使用直接调用
        print("void 你好");
      }
    
      //定义方法 执行 3 + 4
      //public static int add1 () {
      //  int result = 3 + 4;
      //  return result;
      //}
    
      // 定义实现两数求和的加法运算
      public static int add (int x, int y) {
        int result = x + y;
        return result;
      }
    
      //定义没有返回值的方法  void表示方法没有返回值
      public static void print (String s) {
        System.out.println("我自己来输出" + s);
        //return; //可以有可以没有
      }
    
    
    }

    练习: 键盘录入一个数据n(1<=n<=9),输出对应的nn乘法表

    import java.util.Scanner;
    
    /**
     *
     * 练习:
        键盘录入一个数据n(1<=n<=9),输出对应的nn乘法表
     */
    public class Exercise {
    
      public static void main(String[] args) {
        //调用方法
        // 2 x 2乘法表
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        printMulti(n);
    
      }
    
    
      //定义一个方法来完成输出n x n乘法表
      public static void printMulti(int n) {
        for (int i = 1; i <= n; i++) {
    
          for (int j = 1; j <= i; j++) {
            System.out.print(j + "x" + i + "=" + j * i + "  ");
          }
          System.out.println();
        }
      }
    
    }

    方法重载(overload)

    在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数参数类型不同参数顺序不同)

    为什么呢?1. 二义性 2. 方法签名

    package com.method.overloads;
    
    /**
     *
     * 方法重载(overload) 在同一个类中,允许存在一个以上的同名方法,
     *  a.只要它们的参数个数
     *  b.参数类型不同
     *  c.参数顺序不同: 不是指形式参数的变量名顺序不同,而是指形式参数类型顺序
     *
     * 编译器如何秋分方法呢? 通过方法签名 方法签名:
     * 方法名 + 参数列表 比如 add(int, int)
     *                     add(double, dobule)
     */
    public class OverLoadDemo {
    
      public static void main(String[] args) {
    
        int a = 1;
        int b = 2;
        //int add = add(a, b, 10);
        //double c = 1.1;
        //double d = 2.2;
        //double doubleAdd = add(c, d);
        //
        //add(1,2);
    
        //int call = add(a, b);
        //add(a, b);
      }
    
      //两数相加
      public static int add(int x, int y) {
        System.out.println("int add");
        return x + y;
      }
    
      //public static double add(int x, int y) {
      //  return x + y;
      //}
    
    
      //实现3数相加
      public static int add(int x, int y, int z) {
        return add(x, y) + z;
      }
    
      //参数类型不同
      public static double add(double x, double y) {
        System.out.println("double add");
        return x + y;
      }
    
      //参数顺序不同
      public static int add(int y, byte x) {
        return x + y;
      }
    
      public static int add(byte y, int x) {
        return x + y;
      }
    
    }

     

    注意:

    与返回方法重载与返回值类型无关,只看方法名和参数列表。(为什么呢?思考一下)

    package com.method.overloads;
    
    /**
     *
     * 比较两个数据是否相等。
     * 参数类型分别为 两个byte类型,
     *              两个short类型,
     *              两个int类型
     *              两个long类型
     * 并在main方法中进行测试
    
     */
    public class Exercise {
    
      public static void main(String[] args) {
    
        byte b = 1;
        short c = 2;
        long a  = 1L;
        long d = 100L;
        equals(b,c);//equals(byte,short)调用equals(short,short),不需要完全一样,JVM会自己选择;
        equals(a,d);
      }
    
    
      public static boolean equals(byte a, byte b) {
        System.out.println("byte equals");
        return a == b;
      }
    
    
      public static boolean equals(short a, short b) {
        System.out.println("short equals");
        return a == b;
      }
    
    
      public static boolean equals(int a, int b) {
        System.out.println("int equals");
        return a == b;
      }
    
      public static boolean equals(long a, long b) {
        System.out.println("long equals");
        return a == b;
      }
    }

    方法重载练习

    比较两个数据是否相等。参数类型分别为两个byte类型,两个short类型,两个int类型,两个long类型,并在main方法中进行测试

    二、数组

    假设一个班有80个人,我们现在需要统计,其某一门课程的平均成绩,思路很简单,先求和,在平均,想一想,如果使用我们之前所学的知识,该怎么做呢?

    大致想一想都会觉得真的好麻烦!!!

    为了应对以上的使用场景,我们就需要学习数组。

     

    package com.array;
    
    /**
     *
     *
     *假设一个班有80个人,我们现在需要统计,其某一门课程的平均成绩
     */
    public class Demo1Intruduction {
    
      public static void main(String[] args) {
        // 1.定义80个变量
        // 2.用这80个变量存储80个同学的成绩
        // 3. 求和表达式 80变量的求和  a1 + a2 + ... + a80
    
      }
    
    }

     

    数组的概念(一组数据) 相同数据类型的数据元素的有序集合

    存储多个数据元素 这多个数据元素的数据类型必须一致(为什么呢?)

    数组的定义格式

    格式1:

    数据类型[ ] 数组名;

    格式2:

      数据类型 数组名[ ];

      注意,这只是数组的定义,如何给定义好的数组“赋值”呢

     

     图:数组的概念

     

    package com.array;
    
    /**
     *
     * 数组中究竟可以存储哪些类型的数据呢?
       基本类型数据  byte short int char double float…
       引用类型数据  对象  对象数组
    
        数组的定义格式
        格式1:数据类型[] 数组名;   有点变量定义  int a = 1; int a = 1;
        格式2:数据类型 数组名[];
    
        数组的初始化
        1.Java中的数组必须先初始化,然后才能使用。
        2.所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋初值
    
        动态初始化
        初始化时程序猿只指定数组长度,由jvm为数组分配初始值。
    
        静态初始化
        初始化时指定每个数组元素的初始值,由系统决定数组长度。
        int[] a = {1, 2, 3}
    
        数组的动态初始化
        格式: 数据类型[] 数组名 = new 数据类型[数组长度];
        数组长度其实就是数组中元素的个数。
        int[]  arr = new int[3];
    
     */
    public class Demo2Array {
    
      public static void main(String[] args) {
        //数组定义的格式  存放int类型值的数组
        //格式1
        int[] arr;  //官方推荐的写法
    
        //格式2 声明int类型的数组
        int arr1[];
    
        // 声明了数组,使用之前必须赋予初值
        //System.out.println(arr);
    
        {
          int a;
        }
        //System.out.println(a);
    
        //数组的动态初始化
        //格式: 数据类型[] 数组名 = new 数据类型[数组长度];
        int[] array = new int[3];
      }
    
    }

    数组的初始化

    Java中的数组必须先初始化,然后才能使用。

    所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋初值

    数组的初始化方式

    • 动态初始化-------初始化时程序猿只指定数组长度,由系统为数组分配初始值。
    • 静态初始化-------初始化时指定每个数组元素的初始值,由系统决定数组长度。

     

    数组的动态初始化

      格式: 数据类型[] 数组名 = new 数据类型[数组长度];

          数组长度其实就是数组中元素的个数。

          int[] arr = new int[3];

      如果清楚地了解数组的初始化过程,那我们就必须知道,数组初始化过程中,究竟在Java虚拟机内存中做了哪些工作。

    Java虚拟机内存模型

      一个Java程序在虚拟机运行的过程中,

      1. 在内存中需要保存很多中类型的数据。比如局部变量,数组等等。局部变量:定义在方法体中的变量
      2. 不同类型的数据,其使用方式和生命周期,都不相同。
      3. 为了更好的管理这些不同类型的数据,jvm将自己的内存空间划分为不同的内存区域,各个区域针对不同类型的数据,其内存空间有不同的管理方式。
    • 栈 存储局部变量             迄今为止我们代码中几乎所有的变量都在栈(Stack)
    • 堆 存储new出来的东西             数组,对应的存储空间在堆中(Heap)
    • 方法区 (后面讲)
    • 本地方法栈 (系统相关)       java语言   可以调用c/c++
    • 程序计数器               指明代码执行的位置       

    图:栈上变量和堆上变量的不同

     

     图:JVM内存模型

     

     图:数组的动态初始化

     

    Java中数组的内存图解

    图解1: 定义一个数组,输出数组名及元素。然后给数组中的元素赋值,再次输出数组名及元素。

    package com.array;
    
    /**
     *
     * 图解1:
         定义一个数组,输出数组名及元素。然后给数组中的元素赋值,再次输出数组名及元素。
     */
    public class Demo3ArrayMap {
    
      public static void main(String[] args) {
    
        //定义一个数组,输出数组名及元素。然后给数组中的元素赋值,再次输出数组名及元素。
        int[] a = new int[3];
        //输出数组名
        System.out.println(a); // [I@4554617c   [表示一维数组  I整数类型  4554617c数组实际存储的首地址
        //输出
        System.out.println(a[0]);
        System.out.println(a[1]);
        System.out.println(a[2]);
    
        //给数组元素赋值
        a[0] = 10;
        a[1] = 100;
        System.out.println(a[0]);
        System.out.println(a[1]);
        System.out.println(a[2]);
    
      }
    
    }

    图:单个数组 

     

    图解2: 定义两个数组,分别输出数组名及元素。然后分别给数组中的元素赋值,分别再次输出数组名及元素。

     

     1 package com.array;
     2 
     3 /** 6  *    图解2:
     7         定义两个数组,分别输出数组名及元素。
     8         然后分别给数组中的元素赋值,分别再次输出数组名及元素。
     9  */
    10 public class Demo4ArrayMap {
    11 
    12   public static void main(String[] args) {
    13 
    14     int[] arr1 = new int[3];
    15     System.out.println(arr1); //[I@4554617c
    16 
    17     System.out.println(arr1[0]);
    18     System.out.println(arr1[1]);
    19     System.out.println(arr1[2]);
    20     System.out.println("--------------------------------------");
    21 
    22     int[] arr2 = new int[2]; //[I@74a14482
    23     System.out.println(arr2);
    24     System.out.println(arr2[0]);
    25     System.out.println(arr2[1]);
    26 
    27     arr1[0] = -100;
    28     System.out.println(arr1); //[I@4554617c
    29     System.out.println(arr1[0]);
    30     System.out.println(arr1[1]);
    31     System.out.println(arr1[2]);
    32 
    33     arr2[1] = 30;
    34     System.out.println(arr2); //[I@74a14482
    35     System.out.println(arr2[0]);
    36     System.out.println(arr2[1]);
    37 
    38 
    39   }
    40 
    41 }

     

     

     图:多个数组


    图解3: 定义两个数组,先定义一个数组,赋值,输出。然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。然后给第二个数组赋值,再次输出两个数组的数组名及元素。

     1 package com.array;
     2 
     3 /** 6  *
     7  *   图解3:
     8         定义两个数组,先定义一个数组,赋值,输出。
     9         然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。
    10         然后给第二个数组赋值,再次输出两个数组的名及元素。
    11  */
    12 public class Demo5ArrayMap {
    13 
    14   public static void main(String[] args) {
    15 
    16     byte[] bytes1 = new byte[2];
    17     bytes1[0] = 10;
    18     bytes1[1] = 20;
    19     System.out.println(bytes1); //[B@4554617c
    20     System.out.println(bytes1[0]);
    21     System.out.println(bytes1[1]);
    22 
    23     //然后定义第二个数组的时候把第一个数组的地址赋值给第二个数组。
    24     byte[] bytes2 = bytes1;
    25     bytes2[0] = -10;
    26     bytes2[1] = 110;
    27     System.out.println("------------------第一个数组--------------------");
    28     System.out.println(bytes1);  //[B@4554617c
    29     System.out.println(bytes1[0]);
    30     System.out.println(bytes1[1]);
    31     System.out.println("-------------------第一个数组-------------------");
    32 
    33     System.out.println("------------------第二个数组--------------------");
    34     System.out.println(bytes2); //[B@4554617c
    35     System.out.println(bytes2[0]);
    36     System.out.println(bytes2[1]);
    37     System.out.println("-------------------第二个数组-------------------");
    38 
    39   }
    40 
    41 }

     图:多个引用变量指向同一个数组

     

    数组的静态初始化:

      初始化时指定每个数组元素的初始值,由系统决定数组长度。

    格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};

       int[] arr = new int[]{1,2,3};

    简化写法:

       int[] arr = {1,2,3};

    注意: 简化写法只在数组定义时有效!

     

    package com.array;
    
    /**
     *
     * 数组的静态初始化:
        初始化时指定每个数组元素的初始值,由系统决定数组长度。
    
        格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};
        int[] arr = new int[]{1,2,3};
        简化写法:
        int[] arr = {1,2,3}; //只有在声明数组的时候才能使用
     */
    public class Demo6SaticInit {
    
      public static void main(String[] args) {
    
        //静态初始化,可以指定数组的元素初值,无法指定数组长度
        int[] arr = new int[]{1,2,3};
        //                    0 1 2
    
        int[] arr1 = {10, 21, 53};
        System.out.println(arr1[0]);
        System.out.println(arr1[1]);
        System.out.println(arr1[2]);
    
        //只有在声明数组的时候才能使用
        //arr = {10, 21, 53};
      }
    
    }

     图:静态初始化

     

    数组操作中,常见的两个问题:

      • 数组索引越界 ArrayIndexOutOfBoundsException
      • 空指针异常 NullPointerException

     图:空指针异常

     

     1 package com.array;
     2 
     3 /**
     4  *
     5  *  数组常见异常:
     6  *  数组索引越界  ArrayIndexOutOfBoundsException
     7     空指针异常  NullPointerException
     8 
     9  */
    10 public class Demo7ArrayException {
    11 
    12   public static void main(String[] args) {
    13 
    14     //数组索引越界
    15     //java.lang.ArrayIndexOutOfBoundsException: 3
    16     int[] arr = new int[3]; //包含的元素 位置 0 1 2
    17     //访问了数组中并不存在的索引对应的元素
    18     //System.out.println(arr[3]);
    19 
    20     //空指针异常  NullPointerException
    21     arr = null; // null空常量
    22     System.out.println(arr[0]);
    23   }
    24 
    25 }

    数组遍历(依次输出数组中的每一个元素)

    数组元素逆序

    对取值范围在1~100的数据集合排序

    数组获取最值(获取数组中的最大值最小值)

    数组查表法(根据键盘录入索引,查找对应星期)

    数组元素查找(查找指定元素第一次在数组中出现的索引)

  • 相关阅读:
    Mac nginx 简单文件服务器
    cocos-lua
    Sublime Text 3 快捷键精华版
    VS中dumpbin工具的使用
    【2022新教程】Ubuntu server 20.04如何安装nvidia驱动和cuda-解决服务器ssh一段时间后连不上的问题
    linux如何将一个正在运行的进程转入到后台执行且中断shh连接不被kill掉
    Ubuntu如何修改默认python版本-sudo和不用sudopython不一致怎么办
    Ubuntu中virtual enviroment在sudo下无效怎么办?
    时间复杂度为O(1)的抽样算法——别名采样(alias sample method)
    Luke技术小站公告板
  • 原文地址:https://www.cnblogs.com/dust2017/p/12675704.html
Copyright © 2020-2023  润新知