Java基础入门第四天

Java基础语法

数组操作的2个异常

数组的索引超过范围异常 (索引越界)

程序中访问了不存在的索引, 每个数组的索引范围从0开始,最大的索引=数组的长度-1

public static void main(String[] args) {
 //定义存储int类型的数组
 int[] arr = {1,2,3,4,5};
 //数组中存储5个元素,长度是5个
 System.out.println(arr.length);
 //索引0-4
 //访问不存在的索引
 System.out.println(arr[5]);
 }
数组索引越界异常.jpg

数组的空指针异常

当数组的引用类型变量arr不保存数组的地址了,再操作数组,就出现空指针异常

public static void main(String[] args) {
 int[] arr = {1,2,3,4,5};
 System.out.println(arr);

 arr = null; //数组 = 空 , 不再保存数组在内存中的地址了

 //不能操作数组的任何内容
 System.out.println(arr.length);
 }
空指针异常.jpg
空指针异常-2.jpg

数组的内存问题

两个数组在内存中的表现

每个数组,都会在内存中,开辟空间存储数据, 内存之间是相互独立的,没有关联

一个数组就会占用一个内存空间

public static void main(String[] args) {
 //定义2个数组
 int[] arr1 = new int[]{1,2,3,4,5};
 int[] arr2 = new int[]{6,7,8,9,0};
 //输出数组,看到不同的地址
 System.out.println(arr1);
 System.out.println(arr2);

 System.out.println(arr1[0]);
 System.out.println(arr2[0]);
 }
两个数组内存图.jpg

多个变量指向同一个内存空间

public static void main(String[] args) {
 //定义数组,存储一些元素
 int[] arr1 = {1,2,3,4};

 System.out.println(arr1);

 //将数组arr1的内存地址,赋值到另一个变量
 int[] arr2 = arr1;
 System.out.println(arr2);

 System.out.println(arr1[0]);

 arr2[0] = 100;

 System.out.println(arr1[0]);
 }

数组的常见操作

数组的遍历 (迭代)

所谓数组的遍历,就是将数组中的每一个元素分别取出的过程.

数组的遍历,是数组其他操作的一个最基础的案例

循环遍历取出数组的元素,循环的次数由长度决定

public static void main(String[] args) {
 int[] arr = {2,4,6,8,10};
 //循环遍历数组,取出数组中的每个元素,依次取出
 //数组的长度是5个,索引0-4  for(知道次数)   while(不知道次数)
 for(int i = 0 ; i < arr.length ; i++) {
 //利用循环中的变量i, 作为索引使用,取出数组的元素
 System.out.println(arr[i]);
 }
 }

数组最值获取

取出数组中的最大值,或者是最小值

实现核心思想 : 遍历中进行比较

/*
 * 获取数组的最大值
 * 实现步骤 :
 *   1.定义变量,保存数组0索引上的元素
 *   2.遍历数组,取出数组的每个元素
 *   3.数组的元素和变量,进行比较
 *      如果数组的元素,大于变量
 *      数组的元素,存储在变量中
 *   4.数组全部遍历完成,变量保存的就是最大值
 */
public class ArrayDemo06 {
 public static void main(String[] args) {
 //创建数组
 int[] arr = {1,5,10,2,6,9,0,7};
 //定义变量,保存数组0索引上的元素
 int max = arr[0];
 //遍历数组,取出数组的每个元素
 for(int i = 1 ; i < arr.length ; i++) {
 //数组的元素,和变量max比较
 if(arr[i] > max) {
 //赋值变量
 max = arr[i];
 }
 }
 //数组全部遍历完成,变量保存的就是最大值
 System.out.println("最大值是::"+max);
 }
}
获取数组的最值.jpg

数组的倒序遍历

public static void main(String[] args) {
 int[] arr = {1,3,5,7,9};
 //从数组的最大索引开始遍历
 for(int i = arr.length-1 ; i >= 0 ; i--) {
 System.out.println(arr[i]);
 }
 }

数组拼接为字符串

任意数组 : int[] arr = {1,2,3,4,5,6,7}, 遍历数组,取出元素,元素拼接为一个字符串

输出的格式 [1,2,3,4,5,6,7]

/*
 *   输出的格式 [1,2,3,4,5,6,7]
 *   数组遍历,拼接成上面的格式
 *   解决最后一个逗号问题 :
 *     判断循环变量 i , 如果i的值,到达了数组的最大索引
 *     字符串拼接] ,而不是逗号
 * 
 */
public class ArrayDemo08 {
 public static void main(String[] args) {
 //创建数组
 int[] arr = {1,2,3,4,5,6,7};
 //遍历,取出元素,字符串的拼接
 String s = "[";
 for(int i = 0 ; i < arr.length ;i++) {
 //判断i是不是最大索引,如果是拼接]
 if(i == arr.length - 1) {
 s = s + arr[i]+"]";
 }else {
 s = s + arr[i]+",";
 }
 }
 System.out.println(s);
 }
}

数组元素的查找

已知数组 : 在数组中查找一个元素是否存在

元素存在于数组中 : 返回元素所在的索引

元素不存在数组中 : 返回负数

实现功能的核心思想 :

/*
 * 数组元素基本查找
 * 已知数组 : 在数组中查找一个元素是否存在
 元素存在于数组中 : 返回元素所在的索引 
 元素不存在数组中 : 返回负数
 实现功能的核心思想 : 遍历,进行比较 

 实现思想 :
 1\. 定义数组
 2\. 定义要查找的元素
 3\. 定义变量,保存查找后的结果 (数组的索引,或者是负数)
 4: 遍历数组,取出每个元素,和要查找的元素对比
 一旦找到,就不会在进行比较了
 */
public class ArrayDemo09 {
 public static void main(String[] args) {
 //1\. 定义数组
 int[] arr = {1,5,6,7,2,3,8};
 //2\. 定义要查找的元素
 int key = 1;
 //3\. 定义变量,保存查找后的结果 (数组的索引,或者是负数)
 int index = -1;
 //4: 遍历数组,取出每个元素,和要查找的元素对比
 for(int i = 0 ; i < arr.length ; i++) {
 //查找的元素 和 数组的元素相等,找到了
 if(key == arr[i]) {
 //数组的索引,赋值到变量index
 index = i;
 //不需要再计算了吧,结束循环
 break;
 }
 }
 if(index >= 0) {
 System.out.println("元素找到了,在"+index+"这个索引");
 }else{
 System.out.println("抱歉,元素未找到");
 }
 }
}

数组翻转

所谓数组翻转,就是数组中元素的位置发生了转变 不等于倒序遍历

原始数组 : {1,2,3,4,5}

翻转数据 : {5,4,3,2,1}

数组翻转.jpg
/*
 *  数组的翻转
 *
 *  数组最远端的元素换位
 *
 *  实现思想 : 
 *    1\. 定义2个变量
 *      一个变量,保存数组的最小索引
 *      一个变量,保存数组的最大索引
 *
 *    2: 当最小索引,超过最大的索引,程序结束
 *
 *    3: 利用循环实现
 *
 *    4: 第三方变量的位置交换
 */ 
public class ArrayDemo11 {
 public static void main(String[] args) {
 int[] arr = {1,2,3,4,5,0};
 //一个变量,保存数组的最小索引
 //一个变量,保存数组的最大索引
 int min = 0;
 int max = arr.length - 1;
 for(; min <= max  ;) {
 //第三方变量交换位置
 int temp = arr[max]; //临时变量,保存数组的最大索引
 //最小索引的元素,赋值到最大索引
 arr[max] = arr[min];
 //临时变量的值,赋值到小索引上
 arr[min] = temp;

 //位置交换完毕,修改索引
 min++;
 max--;
 }

 //数组遍历
 for(int i = 0 ; i < arr.length ; i++) {
 System.out.println(arr[i]);
 }
 }
}

以上程序小的优化

public static void main(String[] args) {
 int[] arr = {1,2,3,4,5,0};
 //一个变量,保存数组的最小索引
 //一个变量,保存数组的最大索引
 /*  int min = 0;
 int max = arr.length - 1;*/
 for(int min = 0 , max = arr.length - 1; min <= max  ;min++ ,max--) {
 //第三方变量交换位置
 int temp = arr[max]; //临时变量,保存数组的最大索引
 //最小索引的元素,赋值到最大索引
 arr[max] = arr[min];
 //临时变量的值,赋值到小索引上
 arr[min] = temp;
 }

 //数组遍历
 for(int i = 0 ; i < arr.length ; i++) {
 System.out.println(arr[i]);
 }
 }

二维数组

  • 一维数组 : 一个数组,存储的是需要的数据 int[] arr = {123}

  • 二维数组 : 一个数组,存储的元素,是另一个数组. 理解为数组中的数组

    • 定义方式 :
    数据类型[][] array = new 数据类型[3][2]; 
        格式解析 : 定义了一个二维数组
         [3] : 二维数组的长度, 这个二维数组里面存储了3个一维数组
         [2] : 每个一维数组的长度是2
   *   二维数组中,存储的是一维数组的内存地址
        public static void main(String[] args) {
         /*
         * 二维数组的长度是3,存储3个一维数组
         * 每个一维数组,可以存储2个元素
         */
         int[][] array = new int[3][2];
         System.out.println(array);//  [[I@15db9742
        ​
         //思考?
         System.out.println(array[0]); // [I@6d06d69c
        }
二维数组的内存图.jpg
*   定义方式:
        数据类型[][] array = new 数据类型[][]{}
        创建数组直接赋值元素
        public static void main(String[] args) {
            int[][] array = new int[][] { {1,2},{3,4,5,6},{7,8,9}  };
            System.out.println(array);
            //思考, 输出5
            System.out.println(array[1][2]);

            //数组的越界异常
            System.out.println(array[2][2]);
        }
*   定义方式:
        数据类型[][] array = {};
public static void main(String[] args) {
            int[][] array = { {1,2,3},{4,5},{6,7,8,9,0} };
            System.out.println(array);
        }

遍历

二维数组的遍历 : 和一维数组遍历几乎是一样的

利用嵌套循环,双for, 外循环,遍历二维数组,内循环,遍历一维数组

public static void main(String[] args) {
 int[][] array = { {1,2,3},{4,5},{6,7,8,9,0} };
 //外循环,遍历二维数组,取出里面的3个一维数组
 for(int i = 0 ; i < array.length; i++) {
 //System.out.println(array[i]);
 //内循环,遍历每个一维数组
 for(int j = 0; j <array[i].length;j++ ) {
 System.out.print(array[i][j]);
 }
 System.out.println();
 }
}

方法

方法概念

方法(Method)称为函数(Function)

方法 : 在程序中是一个可以完成某个功能的独立代码片段

  • 某个功能 : 只要可以实现的都是功能 (求和)

  • 独立代码 : 方法是在一个{} 实现的, 不同的方法之间是没有联系的

方法好处 : 可以将重复的代码抽取出来,方便我们反复应用.

方法定义

  • 定义格式
修饰符 返回值类型 方法名(参数列表){
  方法体,主体
  return ;
}
*   修饰符 : 目前我们很多点没有讲解,现在就是固定用法 `public static`

*   返回值类型 : 本质上是数据类型,方法是实现功能的代码,功能实现完毕后应该是有结果的,结果的数据类型

*   方法名 : 标识符,自定义, 见名知意

*   参数列表 : 方法要实现的功能中,是否会有未知的数据,就是参数列表

*   方法体 : 写完成功能的代码

方法定义的练习

  • 要求 : 使用方法技术,实现两个整数的求和
     /*
     * 我们自己定义方法,实现需求   实现两个整数的求和
     * 2个分析 : 
     *   功能计算后的结果是什么,还是整数 返回值
     *   功能计算中是否存在未知的数据, 两个整数就是未知的
     *     写在方法的参数列表,  定义2个整数类型变量
     */
     public static int sum(int a, int b) {
     // 方法体 : 写完成功能的代码
     return a + b;
     }

方法的调用

什么是方法的调用 : 就是让我们写好的方法执行起来

如何调用方法 : call name 叫名字

传递方法的参数, 接收方法的返回值结果

public static void main(String[] args) {
 //调用写的方法 sum, 明确方法中的2个未知数
 int i = sum(5,6); // 11
 System.out.println(i);
 }
 /*
 * 我们自己定义方法,实现需求   实现两个整数的求和
 * 2个分析 : 
 *   功能计算后的结果是什么,还是整数 返回值
 *   功能计算中是否存在未知的数据, 两个整数就是未知的
 *     写在方法的参数列表,  定义2个整数类型变量
 */
 public static int sum(int a, int b) {
 // 方法体 : 写完成功能的代码
 return a + b;
 }
方法的调用过程.jpg

方法调用的内存图

方法的运行,是在方法栈运行.

方法的压栈和方法的弹栈,方法进入内存(栈)到达底部, 栈内存特点是先进去的后出来.

方法执行的内存图.jpg

方法定义的注意事项 (匹配)

  • 方法不能定义在另一个方法中,写在类中

  • 方法的定义没有先后顺序的

  • 方法定义的返回值类型,必须和return后面的类型一致

  • 调用方法传递参数也要一致

  • 如果方法定义上,返回值是void, 你却返回了值

方法定义的练习

  • 定义方法 : 实现任意整数的乘法表
   public static void main(String[] args) {
     //调用打印乘法表的方法
     printChengFaBiao(7);
     }
     /*
     * 定义方法 : 实现任意整数的乘法表
     * 分析:
     *  返回值: 功能实现后,结果的数据类型, 没有返回结果  void
     *  方法参数: 实现功能的未知数, 任意整数
     *
     *  方法的返回值没有,void 方法里面可以不写 return
     */
     public static void printChengFaBiao(int num) {
     //实现乘法表的功能
     for(int i = 1 ; i <= num ; i++) {
     for(int j = 1; j <= i ; j++) {
     System.out.print(j+"*"+i+"="+j*i+"\t");
     }
     System.out.println();
     }
     }
  • 定义方法 : 实现任意数字的高斯算法 1+2+3...+100
public static void main(String[] args) {
 //调用打印乘法表的方法
 //printChengFaBiao(7);

 //调用高斯算法的方法
 int sum = getSum(200);
 System.out.println(sum);
 }
 /*
 * 定义方法 : 实现任意数字的高斯算法 1+2+3...+100
 * 分析:
 *  返回值: 功能实现后,结果的数据类型, 结果是求和的数, 整数int
 *  方法参数: 实现功能的未知数, 任意整数
 */
 public static int getSum(int num) {
 //定义变量,保存求和的结果
 int sum = 0;
 for(int i = 1 ; i <= num ; i++) {
 sum = sum + i;
 }
 //计算的结果,返回
 return sum;
 }
 /*
 * 定义方法 : 实现任意整数的乘法表
 * 分析:
 *  返回值: 功能实现后,结果的数据类型, 没有返回结果  void
 *  方法参数: 实现功能的未知数, 任意整数
 *
 *  方法的返回值没有,void 方法里面可以不写 return
 */
 public static void printChengFaBiao(int num) {
 //实现乘法表的功能
 for(int i = 1 ; i <= num ; i++) {
 for(int j = 1; j <= i ; j++) {
 System.out.print(j+"*"+i+"="+j*i+"\t");
 }
 System.out.println();
 }
 }

方法调用上的总结 (调用方式)

  1. 赋值调用

    • 接收方法的返回值结果
  2. 输出语句调用

    • 直接将方法的调用,写在输出语句中
  3. 直接调用,不接收任何结果

  4. 如果方法返回值类型是 void , 不能接收返回值

public static void main(String[] args) {
 //1: 赋值调用,方法必须有返回值
 int i = sum(1,2);
 System.out.println(i);

 //2: 输出语句调用,方法直接放在输出语句
 System.out.println( sum(7,8) );

 //3: 直接调用,不接收任何结果
 sum(1,5);

 Scanner  sc = new Scanner(System.in);
 System.out.println( sc.nextInt() );
 //System.out.println( print()  );
 }
 public static void print() {
 System.out.println("这是一个void方法");
 }

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

方法的重载

方法的重载(overload) : 在同一个类中,允许方法名字是相同的,只要方法的参数列表不一致,这些方法就是重载现象.

方法的重载 : 和修饰符,返回值无关

参数列表不一致 :

  • 包含参数的个数不同

  • 参数的数据类型不同

  • 参数的顺序的不同

  • 以上三个,只要有一个不同,就是重载

public static void main(String[] args) {
 //function();
 }
 /*
 * 写方法,看其他的方法,是否与本方法重载
 */
 public static void function() {

 }
 public static void function(int a) {

 }

 public static int function(double a) {
 return 0;
 }
​
 void function(int a, int b) {

 }
 public static void function(double b,int a) {

 }

 public static void function(int a, double b) {

 }<
  • 方法重载调用练习
    public static void main(String[] args) {
     function((byte)1);
     function((short)1);
     function(1L);
     }

     public static void function() {
     System.out.println("这是无参数的方法");
     }

     public static void function(byte b) {
     System.out.println("字节型参数的方法: "+b);
     }

     public static void function(short s) {
     System.out.println("短整型参数的方法: "+s);
     }

     public static void function(int i) {
     System.out.println("整型参数的方法: "+i);
     }

     public static void function(long l) {
     System.out.println("长整型参数的方法: "+l);
     }
  • 方法重载练习

    需求 : 方法定义实现乘法表

    用户如果传递参数,就按照他传递参数输出乘法表

    用户不传递参数,输出99的, 默认

/*
 *   需求 : 方法定义实现乘法表
 用户如果传递参数,就按照他传递参数输出乘法表
 用户不传递参数,输出99的, 默认

 本案例的存在的问题 : 代码出现了重复 (很大重复)
 进行简化,不能有这么大的重复

 方法: 共性代码的抽取
 */
public class MethodDemo07 {
 public static void main(String[] args) {
 printChengFaBiao(5);
 }

 /*
 * 写有参数的方法,传递什么,输出什么
 */
 public static void printChengFaBiao(int num) {
 //实现乘法表的功能
 for(int i = 1 ; i <= num ; i++) {
 for(int j = 1; j <= i ; j++) {
 System.out.print(j+"*"+i+"="+j*i+"\t");
 }
 System.out.println();
 }
 }

 /*
 * 写无参数的方法,实现输出99乘法表
 * 上面的方法,是带有参数的方法,传递9,就是99乘法表
 * 在本方法中,调用上面的方法,传递9
 */
 public static void printChengFaBiao() {
 printChengFaBiao(9);

 //实现乘法表的功能
 /*
 * for(int i = 1 ; i <= 9 ; i++) { for(int j = 1; j <= i ; j++) {
 * System.out.print(j+"*"+i+"="+j*i+"\t"); } System.out.println(); }
 */
 }
}

方法参数的传递效果

  • 方法的参数是基本数据类型
public static void main(String[] args) {
 //定义2个变量
 int a = 1;
 int b = 2;
 //调用方法change,传递实际参数
 change(a, b);
 System.out.println(a); // a = 1
 System.out.println(b); // b = 2
 }
 /*
 * 定义方法,传递2个整数值
 * 不返回
 */
 public static void change(int a, int b) {
 a = a + b;
 b = b + a;
 }
方法的参数是基本数据类型.jpg
  • 方法的参数是引用数据类型
    public static void main(String[] args) {
     int[] arr = {1,2,3};
     System.out.println(arr[0]); // 1
     //调用方法change,传递数组,传递到方法参数的也是内存的地址
     change(arr);
     System.out.println(arr[0]); // 100
     }

     //change方法参数,写数组, 方法参数接收到的也是地址
     public static void change(int[] arr) {
     //修改数组中的元素值
     arr[0] = 100;
     }
方法的参数问题_引用数据类型.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355