• 不就是Java吗之数组的定义和使用


    一、数组的基本概念

    1.1 什么是数组?

    image-20220608150208505

    数组是存放相同数据类型的集合,在内存中是一段连续的内存空间

    1.2 数组的创建和初始化

    1.2.1 创建

    public static void main(String[] args) {
            //1.中括号里面不能有数字
            int[] array1 = {1,2,3,4,5};//最常用
            //2.中括号里面不能有数字
            int[] array2 = new int[]{1,2,3,4,5};//跟第一种一样,写法更复杂
            //3.不确定数组具体元素
            int[] array3 = new int[10];//未初始化,里面默认为0
            array3[0] = 1;//初始化要这样
            
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    public static void main(String[] args) {
            double[] array = new double[10];//每个元素都是0
            String[] array2 = new String[10];//Java里面支持字符串数组,他的每个值初始化都是null
        	boolean[] array3 = new Boolean[10];//默认都是false
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2.2 初始化

    1.2.2.1 动态初始化

    未指定元素具体值

    int[] array = new int[10];//未指定元素具体
    
    • 1

    1.2.2.2 静态初始化

    定义的同时并初始化

    int[] array = new int[]{0,1,2,3};//定义的同时并初始化
    
    • 1

    1.2.2.3 注意事项

    1. 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。

    2. 静态初始化时,{}中数据类型必须与[]前数据类型一致。

    3. 静态初始化可以简写,省去后面的new 类型[]。但是编译的时候,还是会还原回来的

    4. 其实数组创建也可以用C语言的形式

      int array[10] = {1,2,3};
      
      • 1
    5. 不确定数组具体内容,使用动态初始化(即创建方法3)

    6. 初始化也可以分成两行写

      int[] array1;
      array = new int[10];
      
      int[] array2;
      array2 = new int[]{1,2,3};
      
      //这种写法不能省略new int[],否则会编译失败
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      image-20220608203919527

      另外,不简写的话,可以重复定义多次

      int[] array1;
      array1 = new int[]{1,2,3};
      array1 = new int[]{11,22,33};
      
      • 1
      • 2
      • 3

    1.3 数组的使用

    1.3.1 数组中元素的访问

    数组在内存中是一段连续的空间,下标是从0开始的,数组可以通过下标来访问任意位置的元素

    image-20220608204526769

    public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
            //1.既可以通过下标访问元素
            System.out.println(array[3]);//访问下标为3,实际上值为4的元素
            //2.又可以通过下标修改元素
            array[4] = 55;//下标为4,实际上值为5的元素被修改成了55
            System.out.println(array[4]);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    要注意,不要越界

    public static void main(String[] args) {
            int[] array = {1,2,3,4,5};//数组长度为5,最大下标为4
            System.out.println(array[99]);//严重越界!!!
        }
    
    • 1
    • 2
    • 3
    • 4

    image-20220608210124786

    1.3.2 遍历数组

    两种方式

    1. for循环:快捷键for+i

    2. for-each循环:加强版的for循环

      public static void main(String[] args) {
              int[] array = {1,2,3,4,5};
         		//在数组中,我们可以通过 数组对象.length 来获取数组长度
              //方式1:for循环遍历
              for (int i = 0; i < array.length; i++) {
                  System.out.println(array[i]);
              }
              //方式2:for-each循环
              //不仅可以打印数组,还可以打印集合当中的元素
              //而且不需要用到下标
              for (int x : array) {
                  System.out.print(x + " ");//其实就是把数组元素对应的值赋给x,然后打印x
              }
              System.out.println();
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      image-20220608211235658

    我们还可以通过Java官方提供的工具打印数组

    public static void main(String[] args) {        
            //Arrays:工具类->帮助我们操作数组,他的返回值是String
            String ret = Arrays.toString(array);
            System.out.println(ret);
            //直接可以写成一句
            //System.out.println(Arrays.toString(array));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、数组是引用类型

    2.1 初识JVM的内存分布

    首先,我们先了解一下:引用

    引用是一个变量,里面存储的是地址

    int[] array = {1,2,3,4};//array1这个引用,引用了(指向了) {1,2,3,4}这个对象
    //引用和指向代表的是一个意思
    
    • 1
    • 2

    那么,我们再来看一下初识JVM的内存分布

    image-20220608212913017

    Java虚拟机栈:我们常说的栈(局部变量…)

    Java本地⽅法栈:运⾏⼀些由C/C++代码编写的程序【JVM其实是⼀个软件,是⼀个由C/C++代码编写的软件】

    堆:只要是对象,都在堆上分配内存(数组…)

    程序计数器:存放⼀些指令

    方法区:静态的成员变量…

    划分内存的好处:方便管理

    image-20220608213155612

    image-20220608213825738

    我们来看这段代码

    public static void main(String[] args) {
            int[] array = {1,2,3};
            System.out.println(array);//[I@1b6d3586
        }
    
    • 1
    • 2
    • 3
    • 4

    image-20220608224223870

    2.2 基本类型变量与引用类型变量

    基础类型变量,存放的是数值

    引用类型变量,存放的是地址

    1.当两个数组指向同一块内存空间时

    public static void main(String[] args) {
            int[] array1 = {1,2,3,4};
            int[] array2 = array1;//array2 引用了 array1 引用的对象(不是引用指向引用)
            System.out.println("array1" + Arrays.toString(array1));
            System.out.println("array2" + Arrays.toString(array2));
    
            System.out.println("-------------------");
    
            array2[0] = 100;
            System.out.println("array1" + Arrays.toString(array1));
            System.out.println("array2" + Arrays.toString(array2));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image-20220608225238121

    image-20220608225714649

    2.数组内容相同,不代表他们俩就一模一样

    public static void main(String[] args) {
            int[] array1 = {1,2,3,4};
            int[] array2 = {1,2,3,4};
            System.out.println(array1);
            System.out.println(array2);//两个数组地址不同
        }
    //备注:new出来的就是新的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    image-20220608225842349

    image-20220608230151630

    2.3 再谈引用变量

    public static void main(String[] args) {
            int[] array1 = new int[3];
            array1[0] = 10;
            array1[1] = 20;
            array1[2] = 30;
    
            int[] array2 = new int[]{1,2,3,4,5};
            array2[0] = 100;
            array2[1] = 200;
    
            array1 = array2;
            array1[2] = 300;
            array1[3] = 400;
            array1[4] = 500;
    
            System.out.println(Arrays.toString(array2));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    image-20220609195409149

    2.4 关于null

    null代表不指向任何对象

    当数组被赋值为null的时候,针对他的操作,都会造成空指针异常

    public static void main(String[] args) {
            int[] array = null;//引用类型赋值为null->代表array这个引用不指向任何对象,这时候对他进行操作,就会空指针异常
            array[0] = 1;
            System.out.println(array.length);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image-20220608225001644

    注意:在Java中,并没有约定null跟0号地址的内存有关联

    小猫分隔符

    小结:

    1. 引用能指向引用吗?

      不能!引用只能指向对象

      array1 = array2;//代表array1这个引用 引用了(指向了)array2所引用的对象
      
      • 1
    2. ⼀个引用能同时指向多个对象吗?

      不能同时.一个引用只能同时指向一个对象

      image-20220609200536037

    3. 引用一定在栈上吗?(就是我们画的两个框框,左边的那个)

      不是的.现在之所以把它画在栈上,是因为我们目前只是接触到局部变量,还没有接触成员变量,后面会接触到

      public class Main {
          public int[] array = {1,2,3,4,5,6,7,8};//成员变量->在堆上
          
          public static void main7(String[] args) {
              int[] array1 = {1,2,3,4};//局部变量->在栈上
              array1 = new int[]{11,12,13,14};
              array1 = new int[]{6,7,8,9};
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    4. 引用赋值为null代表啥?

      int[] array = null;//代表这个引用 不指向任何对象
      
      • 1

    三、数组的使用

    3.1 保存数据

    public static void main(String[] args) {
            int[] array = {1,2,3,4,5};
       		
            for (int i = 0; i < array.length; i++) {
                System.out.println(array[i]);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2 作为函数的参数

    3.2.1 参数为基本数据类型

    我们之前在方法的时候讲过,形参的改变不会影响实参

    public class TestDemo2 {
        public static void func(int a) {
            a = 20;
        }
        public static void main(String[] args) {
            int x = 10;
            func(x);
            System.out.println(x);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    image-20220609202041653

    那么传过去的数据是数组类型也是这样

    3.2.2 参数为引用数据类型

    public static void func(int[] arr) {
            arr = new int[]{11,22,33,44};
        }
        public static void main(String[] args) {
            int[] array1 = {1,2,3,4};
            func(array1);
            System.out.println(Arrays.toString(array1));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220609202734090

    public static void func(int[] arr) {
            arr[0] = 100;
        }
        public static void main(String[] args) {
            int[] array1 = {1,2,3,4};
            func(array1);
            System.out.println(Arrays.toString(array1));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220609203113927

    上面这两种方式,虽然都是传了地址,但是他们干的事不太一样

    3.3 作为函数的返回值

    public static int[] func5() {
        int[] array = {1,2,3,4};
        return array;
    }
    public static void main11(String[] args) {
        int[] ret = func5();//返回的是数组,用数组接收
        System.out.println(Arrays.toString(ret));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220609203654567

    四、数组的相关练习

    4.1 数组转字符串

    写⼀个函数将 数组以字符串的形式进行输出 [1, 2, 3, 4]

    public class TestDemo1 {
        public static String myToString(int[] array) {
            String ret = "[";
            for (int i = 0; i < array.length; i++) {
                ret += array[i];
                if(i != array.length - 1) {
                    ret += ",";
                }
            }
            ret += "]";
            return ret;
        }
        public static void main(String[] args) {
            int[] array = {1,2,3,4};
            String ret = myToString(array);
            System.out.println(ret);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    当然,我们还可以调用Arrays下面的toString

    public static void main(String[] args) {        
            //Arrays:工具类->帮助我们操作数组,他的返回值是String
            String ret = Arrays.toString(array);
            System.out.println(ret);
            //直接可以写成一句
            //System.out.println(Arrays.toString(array));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2 数组的拷贝

    数组拷贝

    方法一:使⽤for循环进行拷贝

    public static void main13(String[] args) {
        int[] array = {1,2,3,4};
        int[] copy = new int[array.length];
        for (int i = 0; i < array.length; i++) {
            copy[i] = array[i];
        }
        System.out.println(Arrays.toString(copy));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方法二:Arrays.copyOf(你要拷贝的数组,新的长度)

    public static void main14(String[] args) {
        int[] array = {1,2,3,4};
        //虽然是发⽣了拷贝 也可以看做是 扩容
        int[] copy = Arrays.copyOf(array,array.length);
        int[] ret = Arrays.copyOfRange(array,1,3);//这种方法需要接收返回值
        System.out.println(Arrays.toString(copy));//[1,2,3,4]
        System.out.println(Arrays.toString(ret));//[2,3]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方法三:System.arraycopy你要拷贝的数组,开始拷贝的下标,目的地数组,目的地数组的位置,你要拷贝的长度

    public static void main15(String[] args) {
        int[] array = {1,2,3,4};
        int[] copy = new int[array.length];
        System.arraycopy(array,0,copy,0,array.length);
        System.out.println(Arrays.toString(copy));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方法四:array.clone() 产生了一个新的副本

    public static void main(String[] args) {
        int[] array = {1,2,3,4};
        int[] copy = array.clone();
        System.out.println(Arrays.toString(copy));
        System.out.println(array);
        System.out.println(copy);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.3 求数组中元素的平均值

    public static double avg(int[] array) {
        int sum = 0;
        for (int i = 0; i < array.length; i++) {
            sum = sum + array[i];
        }
        return sum*1.0 / array.length;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.4 顺序查找

    public static int search(int[] array,int key) {
        for (int i = 0; i < array.length; i++) {
            if(array[i] == key) {
                return i;
            }
        }
        //如果代码走到这里,要不是没进去for循环,要不就是没找到
        return -1;//返回-1->因为数组没有负数下标
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    Vue3-vscode代码片段
    【BI看板】Superset2.0+图表二次开发初探
    2款Notepad++平替工具(实用、跨平台的文本编辑器)
    Mysql根据经纬度查询半径多少以内的数据,画个圈圈查数据库
    Java中传地址之后重新赋值String字符串也不会发生改变,因为String具有不可变性
    expect脚本中使用scp命令的方法,expect脚本中scp命令获取不了值的问题完美解决方法
    【C++进阶】:AVL树(平衡因子)
    C语言编程小知识分享,希望对你有用
    如何申请百度apikey
    ORB-SLAM2 ---- Tracking::TrackReferenceKeyFrame函数
  • 原文地址:https://blog.csdn.net/m0_53117341/article/details/126051893