JAVA数组和递归

数组

  • 可以理解为一个容器,可以存储多个相同数据类型的数据。
  • 既可以存储基本类型的数据,也可以存储引用数据类型
  • 数组属于引用数据类型
一维数组
  • 定义:

     格式1:数据类型[] 数组名称 = new 数据类型[数组长度];(一般常用这个!)
     int[] a; 	//定义了一个int类型的数组a;
     格式2:数据类型   数组名[];
    
  • 数组初始化:
    a . Java中的数组必须先初始化,然后才能使用。
    b . 所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。

  • 初始化分类

    • 动态初始化:只指定长度,由系统给出初始化值 (每种类型的数组系统给的初始值都不相同)
      int[] arr = new int[3];	//定义了一个int类型的数组arr,这个数组可以存放3个int类型的值。其数值都被自动初始化为0
      
    • 静态初始化:给出初始化值,由系统决定长度(由我们赋值,由系统给定长度)
      int[] arr = {1,2,3,4}   //定义了一个int类型的数组arr,这个数组存放了4个int类型的值,其分别是:1,2,3,4
      
    • 注意事项:
      这两种初始化方式,只能使用一种,不能进行动静结合。
  • 数组的内存图解1 ====>一个数组
    在这里插入图片描述

  • 数组的内存图解2 ====>二个数组
    在这里插入图片描述

  • 数组的内存图解3 ====> 三个引用2个数组
    在这里插入图片描述

  • 数组中的属性:length

    int len = arr3.length;
    Syste.out.println(len);// 输出3
    
  • JAVA中的数组长度一旦给定就不能发生变化了,切记切记!

  • JAVA中的数组名就是一个地址(指向数组在JVM堆中分配的内存区域的头部地址):

    public class List {
        public static void main(String[] args) {
            int[] arr1 = new int[4];
            System.out.println(arr1); //[I@1b6d3586 --> 引用
        }
    }
    
  • JAVA书籍推荐:

    • JAVA核心技术
    • Thinking in java (JAVA编程思想)
    • 深入理解JVM虚拟机
    • 数据结构与算法(从底层开始)
  • 数据类型:基本数据类型4类8种,和引用数据类型(类,数组,接口)

    new出来的都是引用数据类型

  • 在IDEA中快速遍历数组的快捷键:

    arr.length.fori   // 这样就会由IDEA编辑器快速创建一个循环语句
    
  • 数组的名字确实是地址,数组名在参数传递的时候,相当于传递了地址,所以在另一个方法中操作该数组也会对原数组产生变化

    public class GetMaxValueFromArray {
        public static void main(String[] args) {
            int[] arr = {10,20,30,200,40,50,60};
            int max = getMaxValue(arr);
            System.out.println("数组中的最大数值为:"+max); //数组中的最大数值为:200
            System.out.println("------------");
            System.out.println("arr的首地址是:"+arr); //arr的首地址是:[I@1b6d3586
            System.out.println("arr[2]的数值为:"+arr[2]); //arr[2]的数值为:30
            int[] arr2 = getArray(arr);
            System.out.println("arr的首地址是:"+arr2); //arr的首地址是:[I@1b6d3586(未发生变化!)
            System.out.println("arr[2]的数值为:"+arr2[2]); //arr[2]的数值为:0
            System.out.println("----------");
            System.out.println("arr[2]的数值为:"+arr[2]); //arr[2]的数值为:0
        }
    
        private static int[] getArray(int[] arr) {
            arr[2] = 0;
            return arr;
        }
    
        private static int getMaxValue(int[] arr) {
            int max=0;
            for (int i = 0; i < arr.length; i++) {
                max = max>arr[i]?max:arr[i];
            }
            return max;
        }
    }
    
  • java数组操作的两个常见小问题越界和空指针:

  1. ArrayIndexOutOfBoundsException:数组索引越界异常(原因:你访问了不存在的索引。)
  2. NullPointerException:空指针异常(原因:数组已经不在指向堆内存了。而你还用数组名去访问元素。)
  • 数组元素反转
    int temp;
    for (inti=0,j=arr.length-1;i<j;i++,j--)
        temp = arr[i];
    	arr[i] = arr[j];
    	arr[j] = t;
    
二维数组
  • 定义:
    其实二维数组其实就是每一个元素为一维数组的数组。

  • 二维数组的格式:

    数据类型[][] 变量名 = new 数据类型[m][n];
    
    • m 表示这个二维数组有多少个一维数组 必须写上
    • n 表示每一个一维数组的元素个数 可选(即:可不写)
  • 举例:

    int[][] arr = new int[3][2];
    
    • 定义了一个二维数组arr
    • 这个二维数组有3个一维数组,数组名称分别是arr[0],arr[1],arr[2]
    • 每个一维数组有2个元素,可以通过arr[m][n]来获取(表示获取第m+1个一维数组的第n+1个元素)
  • 注意事项:

    1. 以下格式也可以表示二维数组(这两种方式都不推荐使用!)
      a. 数据类型 数组名[][] = new 数据类型[m][n];
      b. 数据类型[] 数组名[] = new 数据类型[m][n];
    2. 注意下面定义的区别:
      int[] x,y[];
      ---------------------
      x=new int[3];
      y=new int[3][];
      

    区别是:定义了两个数组 一个是一维数组x 一个是二维数组y

  • 二维数组格式1的内存图解
    在这里插入图片描述

  • 二维数组格式2的讲解及其内存图解
    在这里插入图片描述

  • 打印杨辉三角形:

    public class Test {
        public static void main(String[] args) {
            int num =6;
            printYangHuiTriangle(num);
        }
    
        private static void printYangHuiTriangle(int num) {
            int[][] arr = new int[num][num];
            // 初始化:
            for (int i=0;i<arr.length;i++){
                for (int j=0;j<arr[i].length;j++){
                    arr[i][j] = 1;
                }
            }
            // 计算杨辉三角形的数值:
            for (int i=0;i<arr.length;i++){
                for (int j=0;j<=i;j++){
                    if (j!=0 && j!=i){
                        arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
                    }else{
    
                    }
                    System.out.print(arr[i][j]+"\t");
                }
                System.out.println();
            }
    
        }
    }
    -----------------------------
    输出:
    1	
    1	1	
    1	2	1	
    1	3	3	1	
    1	4	6	4	1	
    1	5	10	10	5	1	
    
  • 思考题Java中的参数传递问题及图解:

    A:案例演示
    	看程序写结果,并画内存图解释
    	public static void main(String[] args) {
    
    		int a = 10;
    		int b = 20;
    		System.out.println("a: " + a + ",b: " + b);
    		change(a,b);
    		System.out.println("a: " + a + ",b: " + b);
    
    		int[] arr = {1,2,3,4,5};
    		change(arr);
    		System.out.println(arr[1]);
    	}
    
    	public static void change(int a,int b)  {
    
    		System.out.println("a: " + a + ",b: " + b);
    		a = b;
    		b = a + b;
    		System.out.println("a: " + a + ",b: " + b);
    	}
    
    	public static void change(int[] arr){
    		for(int x = 0 ; x < arr.length ; x++){
    			if(arr[x]%2 == 0){
    				arr[x] *= 2;
    			}
    		}
    	}
    	----------------------------
    	输出为:
    	a: 10,b: 20
    	a: 10,b: 20
    	a: 20,b: 40
    	a: 10,b: 20(局部变量释放后,并没有改变main中的局部变量!值传递)
    	---------
    	4(一维数组中的元素被改变了!引用传递)
    

递归

  • 概述:
    方法定义中调用方法本身的现象
  • 递归注意事项:
    1. 要有出口,否则就是死递归
    2. 次数不能太多,否则就内存(栈空间)溢出
  • 递归解决问题的思想及图解:(待补充!)
    • 思想:拆分合并的思想!
      在这里插入图片描述
  • 画图演示: 递归实现求5的阶乘的内存图(待补充!)
    在这里插入图片描述
  • 递归求解(斐波那契数列)
public class FeiBoNaQie {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你要求的斐波那契数:");
        int num = scanner.nextInt();
        int result = getFeiBoNaQieValue(num);
        System.out.println("第"+num+"个斐波那契数列的结果是:"+result);
    }

    private static int getFeiBoNaQieValue(int num) {
        if(num==1 || num==2){
            return 1;
        }
        return getFeiBoNaQieValue(num-2)+getFeiBoNaQieValue(num-1);
    }
}
----------------------------------
输出:
请输入你要求的斐波那契数:
2020个斐波那契数列的结果是:6765

Java中的内存分配以及栈和堆的区别:

  • 方法也会进栈,方法内的局部变量也是如此!(每次程序调用到一个方法,就将实参赋给形参然后将该方法压入栈顶,进行函数调用!第一个进栈的方法是主函数:main方法!)
  • 存放的是局部变量(在方法定义中或者方法声明上的变量都是局部变量。)
  • 存放的是所有new出来的东西
  • 特点:
    • 每一个new出来的东西都会为其分配一个地址值。

    • 每一个变量都有一个默认的值(参考默认值表格)

    • 使用完毕就变成了垃圾,等待垃圾回收器对其回收

    • 默认值表格:

类型默认数值
byte,short,int,long0
float,double0.0
char‘\u0000’
booleanfalse
引用数据类型null
方法区
本地方法区
寄存器区(CPU使用)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值