【数组,内存图】

模块五. 数组

第一章. 数组

1. 定义数组

1. 问题:如果我们想存储一个数据,我们可以使用变量,但是变量一次只能存储一个数据,所以我们想能不能一次存储多个数据

2. 数组概述:是一个容器,数组本身属于引用数据类型

3. 作用:一次存储多个数据

4. 特点:
a. 既可以存储基本类型的数据,还能存储引用类型的数据

b. 定长(定义数组时长度为多长,最多能存多少个数据)//数组最大的特点也是缺点

5. 定义:
 a. 动态初始化:在定义数组的时候,我们没有给具体的数据,只指定了长度
 	数据类型[] 数组名 = new 数据类型[长度];
		int[] arr = new int[3];
 	或
 	数据类型 数组名[] = new 数据类型[长度];

 	各部分解释:
 		等号左边的数据类型:规定了数组中只能存储什么类型的数据
 		[]:代表的是数组,一个[]代表一维数组,[][]代表二维数组
 		数组名:自己取名字(小驼峰式)
 		new:代表的是创建数组
         等号右边的数据类型:要和等号左边的数据类型一致
         [长度]:指定数组长度,规定了数组最多能存多少个数据,可以少存,但不能多存

 b. 静态初始化:在定义数组的时候,我们直接给了数据
      数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...} -> 不推荐使用
			或
		 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...} -> 不推荐使用
         或 简化的静态初始化   
      数据类型[] 数组名 = {元素1,元素2,...} -> 推荐使用

6. 动态初始化和静态初始化区别:
 a. 动态初始化:定义的时候只指定了长度,没有存具体的数据
             当只知道长度,不知道具体存啥具体的数据时可以使用动态的初始化

 b. 静态初始化:定义的时候就直接知道存什么数据了

2. 数组操作

1. 获取数组的长度

1. 格式:
  数组名.length

2. 注意:
  length 后面并不要带小括号 (),因为length不是数组中的方法,而是数组中的一个属性
public class Demo02Array{
  public static void main(String[] args){
      String[] arr1 = {"ddd","aaa","ccc","sdsd","qwdqw"};
      //定义一个变量 接受数组的长度
      int len = arr1.length;
      System.out.println("len = " + len);
  }
}

2. 索引

1. 概述:元素在数组中存储的位置(编号,下标)

2. 特点:
  a. 索引唯一,不能重复

  b. 索引都是从 0 开始,因此最大索引是数组长度-1

3. 索引的作用:
  我们将来操作元素,必须通过索引来操作
  存数据,要指定索引
  取数据,要指定索引
  查数据,要指定索引

在这里插入图片描述

3. 存储元素

1. 格式:
  数据名[索引值] =;    -> 将等号右边的数据放到数组指定的索引位置上
  arr[0] = 10;
public class Demo03Array {
  public static void main(String[] args) {
      int[] arr = new int[3];
      arr[0] = 100;//将100存到了arr这个数组的0索引上
      arr[1] = 200;//将200存到了arr这个数组的0索引上
      arr[2] = 300;//将300存到了arr这个数组的0索引上
//        arr[3] = 200;//上面的数组长度为3,最大索引是2,没有3索引,所以不能操作不存在的索引

  }
}
public class Demo03Array {
  public static void main(String[] args) {
      int[] arr = new int[3];
      arr[0] = 100;//将100存到了arr这个数组的0索引上
      arr[1] = 200;//将200存到了arr这个数组的0索引上
      arr[2] = 300;//将300存到了arr这个数组的0索引上
//        arr[3] = 200;//上面的数组长度为3,最大索引是2,没有3索引,所以不能操作不存在的索引


      String[] arr2 = new String[3];
      arr2[0] = "张三";
      arr2[1] = "李四";
      arr2[2] = "王五";
  }
}
//键盘录入数据 放到数组中
import java.util.Scanner;

public class Demo04Array {
  public static void main(String[] args) {
      //键盘录入3个整数,存到数组arr里面
      int[] arr = new int[3];
      Scanner sc = new Scanner(System.in);
//        arr[0] = sc.nextInt();
//        arr[1] = sc.nextInt();
//        arr[2] = sc.nextInt();

//        for (int i = 0; i < 3; i++) {
//            arr[i] = sc.nextInt();
//        }
//        //写死了 循环三次

      //优化,数组长度多少,我们就应该循环多少次
      for (int i = 0; i < arr.length; i++) {
          arr[i] = sc.nextInt();
      }
      System.out.println("arr = " + arr);
  }
}
//随机数 放入数组中
public class Demo05Array {
  public static void main(String[] args) {
      int[] arr = new int[3];
      Random rd = new Random();
      int i = rd.nextInt(10) + 1;
      System.out.println("i = " + i);
      arr[0] = i;
      System.out.println("arr[0] = " + arr[0]);
  }
}

4. 取数组元素

1. 格式:
  数组名[索引值]

2. 细节说明
  a. 直接输出数组名,会输出数组在内存中的地址值
  b. 地址值:数组在内存中的一个身份证号,唯一标识,我们可以通过这个唯一标识,到内存中能找到这个数组,从而操作这个数组中的数据
  c. 如果数组中没有存数据,那么直接获取也能获取出来一些数据(元素的默认值)
     默认值:  整数:0
  			小数:0.0
  			字符:'\u0000'  -> 对应的int值是 0 
  			布尔:false
  			引用:null
public class Demo06Array {
  public static void main(String[] args) {
      int[] arr = new int[3];
      System.out.println("arr = " + arr);//[I@682a0b20      直接输出数组名 得到的是数组的地址值
      //获取数组元素
      System.out.println("arr[0] = " + arr[0]);
      System.out.println("arr[1] = " + arr[1]);
      System.out.println("arr[2] = " + arr[2]);
      //整数默认值都是0
  }
}

在这里插入图片描述


5. 遍历数组

1. 遍历:将元素从数组中一个一个的获取出来(循环)
public class Demo06Array {
  public static void main(String[] args) {
      int[] arr = new int[3];
      System.out.println("arr = " + arr);//[I@682a0b20      直接输出			数组名 得到的是数组的地址值
      //获取数组元素
      System.out.println("arr[0] = " + arr[0]);
      System.out.println("arr[1] = " + arr[1]);
      System.out.println("arr[2] = " + arr[2]);
      //整数默认值都是0

      arr[0] = 100;
      arr[1] = 200;
      arr[2] = 300;
      System.out.println("arr[0] = " + arr[0]);//100
      System.out.println("arr[1] = " + arr[1]);//200
      System.out.println("arr[2] = " + arr[2]);//300


      								         System.out.println("****************************************");
      String[] arr2 = new String[3];
      System.out.println("arr2 = " + arr2);
      System.out.println(arr2[0]);//引用数据类型默认值是null
      System.out.println(arr2[1]);//引用数据类型默认值是null
      System.out.println(arr2[2]);//引用数据类型默认值是null

      arr2[0] = "张无忌";
      arr2[1] = "张三丰";
      arr2[2] = "张翠山";
      System.out.println(arr2[0]);
      System.out.println(arr2[1]);
      System.out.println(arr2[2]);

      System.out.println("===========遍历arr数组=======================");
      //数组多长,就循环多少次
      for (int i = 0; i < arr.length; i++) {
          System.out.println(arr[i]);
      }
      System.out.println("===========遍历arr2数组=======================");
      /*
      * 快捷键
      *   数组名.fori
      * */

      for (int i = 0; i < arr2.length; i++) {
      }
  }
}

3. 操作数组时两个常见的问题

1. 数组索引越界异常_ArrayIndexOutOfBoundsException

1. 原因:
  操作的索引超出了数组索引的范围了

2. 空指针异常_NullPointerException

1. 原因:
 当一个对象为null,再调用此对象的其他成员
public class Dem09ArrayException {
 public static void main(String[] args) {
     int[] arr = new int[3];
     System.out.println(arr.length);

      arr = null;
      System.out.println("arr.length = " + arr.length);
 }
}

在这里插入图片描述

4. 数组练习

1. 需求:求出数组中的元素最大值 (元素和元素之间两两比较,取较 大的,一直比较,直到求出最大值)
	步骤:
 1. 定义一个变量max,用来接受两个元素比较之后的较大值
 2. 遍历数组,将每一个元素获取出来进行比较
 3. 判断,如果max小于遍历出来的元素,证明遍历出来的元素大,就将大的重新赋值给 max
 4. 最后输出max,此时max为最大值

2. 随机产生10[0,100]之间的整数,统计既是3又是5,但不是7的倍数的个数
 步骤:
 1. 创建Random对象,用于生成随机数
 2. 定义一个数组,长度为10,用来存放生成的10个数
 3. 定义一个遍历count,用于统计符合条件的数据个数
 4. 遍历数组,判断元素是否符合指定的条件,如果符合,count++
 5. 输出count

3. 用一个数组存储本组学员的姓名,从键盘输入,并遍历显示

4. 需求:
 1. 定义一个数组,int[] arr = {1,2,3,4};
	2. 遍历数组,输出元素按照 [1,2,3,4] 这样的格式

5. 需求:随机501 - 100 之间的整数,统计偶数个数    
     步骤:
     1. 创建Random对象
     2. 定义长度为50的数组
     3. 随机50个存储到数组中
     4. 遍历数组,判断,如果是偶数,count++
     5. 输出count

6. 键盘录入一个整数,找出整数中存储的索引位置        
 步骤:
     1. 创建Scanner对象
     2. 定义数组,随便存几个数据
     3. 遍历数组,在遍历的过程中判断是否和录入的数相等,如果相等,输出索引
     4. 如果查不到,就输出-1,代表没有查到      

7. 数组复制
 public class Demo06Copy {
 public static void main(String[] args) {
     int[] arr1 = {1,2,3,4};
     int[] arr2 = new int[4];

     for (int i = 0; i < arr1.length; i++) {
         arr2[i] = arr1[i];
     }

     for (int i = 0; i < arr2.length; i++) {
         System.out.print(arr2[i] + " ");
     }
 }

1. 如果arr[i]在等号右边,证明是获取值,如果在等号左边,证明是存值
    arr[0] = 100;

    arr2[i] = arr1[i] -> 先看等号右边的,相当于将arr1数组的i索引上的数据,								保存到arr2数组的i索引上

    arr2[0] = arr1[0] -> 先看等号右边的,将arr1的0索引上的元素取出来,保存								到arr2数组的0索引上  

在这里插入图片描述

8. 数组扩容
 需求:
 定义一个数组:int[] arr1 = {1,2,3,4,5}
				将数组由原来的长度扩容到10

public class Demo07Array {
 public static void main(String[] args) {
     int[] oldArr = {1,2,3,4,5};

     //创建新数组
     int[] newArr = new int[10];

     //将老数组中的元素复制到新数组中
     for (int i = 0; i < oldArr.length; i++) {
         newArr[i] = oldArr[i];
     }

     //将新数组的地址值 给 老数组
     oldArr = newArr;

     System.out.println("oldArr.length = " + 			   		oldArr.length);

     for (int i = 0; i < oldArr.length; i++) {
         System.out.println(oldArr[i]);
     }
 }  

在这里插入图片描述

9. 数组合并   
 int[] arr1 = {1,2,3};
 int[] arr2 = {4,5,6};

public class Demo08Array {
 public static void main(String[] args) {
     int[] arr1 = {1, 2, 3};
     int[] arr2 = {4,5,6};
     int[] newArr = new int[arr1.length + arr2.length];

     for (int i = 0; i < arr1.length; i++) {
         newArr[i] = arr1[i];
     }

     for (int i =0; i < arr2.length; i++) {
          newArr[arr1.length + i] = arr2[i];
     }

     for (int i = 0; i < newArr.length; i++) {
         System.out.println(newArr[i]);
     }
 }

在这里插入图片描述

第二章. 内存图

1. 内存的划分

1. 内存:
 可以理解为:"内存条",所有的软件,程序运行起来都会进入到内存中,"占用内存"2. java中,将内存划分成了5块
 a. 栈(重点)(Stack)
 	主要运行"方法",方法的运行都会进"栈内存"运行,运行完毕之后,需要"弹栈",为了腾空间

 b. 堆(重点)(Heap)
 	保存的是"对象,数组",每 new 一次,都会在堆内存中开辟空间,并为这个空间分配一个"地址值",堆内存中的数据都是有"默认值"的

 c. 方法区(重点)(Method Area)
 	代码的"预备区",记录了"类的信息以及方法的信息"
 	方法区中主要保存 class  文件以及其中的信息
 	代码运行之前,需要"先进内存(方法区)",之后,该进栈进栈,该进堆进堆

 d. 本地方法栈(了解)(Native Method Stack):专门运行 native 方法(本地方法)
 本地方法可以理解为堆对java功能的扩充
 有很多功能,java语言实现不了,所以就需要依靠本地方法完成
 (本地方法都是c语言编写)

  e. 寄存器(了解)(pc register) -> 和cpu有关

在这里插入图片描述

2. 一个数组的内存图

模板

在这里插入图片描述
在这里插入图片描述

3. 两个数组的内存图

我们创建了两个数组,在堆内存中开辟了两个不同的空间。此时修改一个空间中的数据不会影响到另外一个空间的数据

在这里插入图片描述

4. 两个数组指向同一片空间内存图

arr2不是new出来的,是arr1直接赋值给的,arr1在内存中保存的是地址值,给了arr2,
那么arr2的地址值和arr1一样,所以此时arr1和arr2指向了堆内存中的同一片空间,(同一个地址值,代表的是同一个数组),此时改变一个数组中的元素会影响到另外一个数组

在这里插入图片描述

第三章. 二维数组

1. 定义二维数组

1. 概述:数组中套了多个数组

2. 定义格式:
  a. 动态初始化
  	数据类型[][] 数组名 = new 数据类型[m][n];
		或者
      数据类型 数组名[][]  = new 数据类型[m][n];    
		或者
      数据类型[] 数组名[] = new 数据类型[m][n];    

		m: 代表的是二维数组的长度(二维数组中存了m个一维数组)
      n:代表的是二维数组中每一个一维数组的长度(每个一维数组中有n个元素)   

      数据类型[][] 数组名 = new 数据类型[m][]; -> 二维数组中的一维数组没有											     被创建

  b. 静态初始化:
		数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...},{元素1,元												素2...}...};
		或者
      数据类型 数组名[][] = new 数据类型[][]{{元素1,元素2...},{元素1,元												素2...}...};    
		或者
      数据类型[] 数组名[] = new 数据类型[][]{{元素1,元素2...},{元素1,元												素2...}...};

		简化静态初始化:
      数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2...}...};
		或者
      数据类型 数组名[][] = {{元素1,元素2...},{元素1,元素2...}...};    
		或者
      数据类型[] 数组名[] = {{元素1,元素2...},{元素1,元素2...}...}; 

在这里插入图片描述

public class Demo01Array {
  public static void main(String[] args){
      int[][] arr1 = new int[2][2];
      int[][] arr2 = new int[2][];

      System.out.println("==========================================");
      String[][] arr3 = {{"孙悟空","唐僧"},{"刘备","关羽","张飞"},{"宋江"},{"林黛玉","贾宝玉"}};
  }
}

使用动态初始化 每一个一维数组长度固定
使用静态初始化,每一个一维数组长度不固定    

2. 二维数组操作

1. 获取长度

1. 格式:
  二维数组名.length

2. 获取每一个一维数组长度,需要先遍历二维数组,将每一个一维数组遍历出来    
public class Demo02Array {
  public static void main(String[] args) {
      String[][] arr1 = {{"孙悟空", "唐僧"}, {"刘备", "关羽", "张飞"}, {"宋江"}, {"林黛玉", "贾宝玉"}};
      System.out.println(arr1.length);
      System.out.println("*************************************************");
      //获取二维数组中每一个一维数组长度      遍历

      for (int i = 0; i < arr1.length; i++) {
//            arr1[i]代表每一个一维数组
          System.out.println(arr1[i].length);
      }

  }

在这里插入图片描述

2. 获取元素

1. 格式:
  数组名[i][j]

  i: 代表的是一维数组在二维数组中的索引位置
  j: 代表的是元素在一维数组中的索引位置    
public class Demo03Array {
  public static void main(String[] args) {
      String[][] arr1 = {{"孙悟空", "唐僧"}, {"刘备", "关羽", "张飞"}, {"宋江"}, {"林黛玉", "贾宝玉"}};
      System.out.println(arr1[0][0]);
      System.out.println(arr1[2][0]);
      System.out.println(arr1[3][1]);
  }
}

在这里插入图片描述

3. 存储元素

1. 格式:
  数组名[i][j] =;

  i: 代表的是一维数组在二维数组中的索引位置
  j: 代表的是元素在一维数组中的索引位置
public class Demo04Array {
  public static void main(String[] args) {
      String[][] arr = new String[2][2];
      arr[0][0] = "张飞";
      arr[0][1] = "李逵";
      arr[1][0] = "刘备";
      arr[1][1] = "宋江";
      System.out.println(arr[0][0]);
      System.out.println(arr[0][1]);
      System.out.println(arr[1][0]);
      System.out.println(arr[1][1]);
  }

4. 数组遍历

1. 先遍历二维数组,将每一个一维数组遍历出来
2. 再遍历每一个一维数组,将元素获取出来    
public class Demo05Array {
  public static void main(String[] args) {
      String[][] arr = new String[2][2];
      arr[0][0] = "张飞";
      arr[0][1] = "李逵";
      arr[1][0] = "刘备";
      arr[1][1] = "宋江";

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

5. 二维数组内存图


public class Demo06Array {
public static void main(String[] args) {
  int[][] arr1 = new int[3][];

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

  arr1[2] = new int[3];

  arr1[2][1] = 100;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值