初级提升 - 数组

返回目录

数组(Array)

    • 数组的简介:数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。数组的基本特点:
      • 长度是确定的,数组一旦被创建,它的大小就是不可以改变的
      • 其元素必须是相同类型,不允许出现混合类型
      • 数组类型可以是任何数据类型,包括基本类型和引用类型
      • 数组变量属引用类型,数组本就是对象,数组中的每个元素相当于该对象的成员变量
      • Java中对象存在于堆中,因此数组无论保存原始类型还是其他对象类型,数组对象本身存储在堆中。
        // 数组声明格式
        type[] 数组名; //建议这种
        type 数组名[];
         
        package me.hzyis.test;
        public class Test {
          public static void main(String[] args) {
            int[] arr01 = new int[10]; //[10]表示数组长度为10,可放置10个元素
            
            String[] arr02 = null; //声明数组,但不赋予任何值,此时栈内存中有arr02变量,但堆内存中什么也没有
            arr02 = new String[5]; //给arr02数组赋值,此时堆内存中创建数组对象String[],在对象中数组各个元素遵守成员变量的规则,比如int默认是0、布尔默认是false
            // 给数组各个元素赋值,索引下标从0开始,范围0到(length-1),也就是0-4
            {
              arr02[0] = "1号元素";
              arr02[1] = "2号元素";
              arr02[2] = "3号元素";
              arr02[3] = "4号元素";
              arr02[4] = "5号元素";
            }
            System.out.println(arr02[0]+"\r\n"+arr02[1]+"\r\n"+arr02[2]+"\r\n"+arr02[3]+"\r\n"+arr02[4]);
            
            double arr03[] = new double[7];
            // 利用循环赋值并输出
            for(int i=0; i<arr03.length; i++) {
              arr03[i] = i+1;
              System.out.println(arr03[i]);
            }
            
            User[] arr04 = new User[4]; //给引用类型数组分配空间
            // 输入内容
            arr04[0] = new User(0001,"黄泽风");
            arr04[1] = new User(0002,"黄泽雨");
            arr04[2] = new User(0003,"黄泽雷");
            arr04[3] = new User(0004,"黄泽电");
            for(int i=0; i<arr04.length; i++) {
              System.out.println(arr04[i].getName()); //输出数组中的name属性
            }
          }
        }
        class User{
          private int id;
          private String name;
          
          public User(int id,String name){
            this.id = id;
            this.name = name;
          }
          public int getId() {
            return id;
          }
          public void setId(int id) {
            this.id = id;
          }
          public String getName() {
            return name;
          }
          public void setName(String name) {
            this.name = name;
          }
        
        }
        
    • 数组的初始化:数组的初始化方式共三种:静态初始化、动态初始化、默认初始化。
      • 默认初始化:
        package me.hzyis.test;
        public class Test {
          public static void main(String[] args) {
            //默认初始化,默认给数组的元素进行赋值,默认的赋值规则和成员变量相同
            int[] i = new int[2]; //int默认为0
            boolean[] b = new boolean[2]; //boolean默认为false
            String[] s = new String[2]; //String默认为null
          }
        }
      • 静态初始化:
        package me.hzyis.test;
        public class Test {
          public static void main(String[] args) {
            int[] a = {2,5,10}; //静态初始化,基本类型数组,直接赋值,赋几个值长度就是几
            // 静态初始化,引用类型数组
            User[] b = {
                new User(0001,"黄泽风"),
                new User(0002,"黄泽雨"),
                new User(0003,"黄泽雷"),
                new User(0004,"黄泽电")
            };
          }
        }
        class User{
          private int id;
          private String name;
          public User(int id, String name) {
            this.id = id;
            this.name = name;
          }
          public int getId() {
            return id;
          }
          public void setId(int id) {
            this.id = id;
          }
          public String getName() {
            return name;
          }
          public void setName(String name) {
            this.name = name;
          }
        }
      • 动态初始化:
        package me.hzyis.test;
        public class Test {
          public static void main(String[] args) {
            int[] i = new int[2]; //动态初始化数组,分配空间
            //给数组元素赋值
            i[0] = 1;
            i[1] = 2;
            System.out.println(i[0] +"\r\n"+ i[1]);
          }
        }
    • 数组的遍历:数组元素下标的合法区间:[0, length-1]。我们可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。
      package me.hzyis.test;
      public class Test {
        public static void main(String[] args) {
          int[] a = new int[4];
          // 初始化数组的值
          for(int i=0; i<a.length; i++) {
            a[i] = 100+1;
          }
          // 读取元素的值
          for(int i=0; i<a.length; i++) {
            System.out.println(a[i]);
          }
        }
      }
    • for-each循环:增强for循环for-each是JDK1.5新增加的功能,专门用于读取数组或集合中所有的元素,即对数组进行遍历。
      package me.hzyis.test;
      public class Test {
        public static void main(String[] args) {
          int[] a = new int[4];
          for(int i=0; i<a.length; i++) {
            a[i] = 100+1;
          }
      	// for-each循环,快速遍历数组
          for(int m:a) {
            System.out.println(m);
          }
        }
      }
    • 数组的拷贝和应用:使用System类中的static void arraycopy(object src,int srcpos,object dest, int destpos,int length)方法,对数组进行拷贝。删除、插入某个数据都可以利用拷贝来完成。
      package me.hzyis.test;
      public class Test {
        public static void main(String[] args) {
          ArrayCopy ac = new ArrayCopy();
          ac.testArray();
          ac.removeElment();
          ac.testRemoveElmentTool();
          ac.extendRange();
          ac.insertArray();
        }
      }
      class ArrayCopy{
        String[] str = {"黄泽风","黄泽雨","黄泽雷","黄泽电"};
        String[] str2 = {"黄泽风2","黄泽雨2","黄泽雷2","黄泽电2"};
        String[] str3 = {"黄泽风3","黄泽雨3","黄泽雷3","黄泽电3"};
        String[] str4 = {"黄泽风4","黄泽雨4","黄泽雷4","黄泽电4"};
        // 测试数组的拷贝
        public void testArray(){
          String[] strBak = new String[6];
          // 拷贝格式:System.arraycopy(src, srcPos, dest, destPos, length);
          // System.arraycopy(<原数组>, <原数组开始位置>, <目标数组>, <目标数组开始位置>, <拷贝长度>);
          System.arraycopy(str, 0, strBak, 1, 4);
          for(int i=0; i<strBak.length; i++) {
            System.out.println(i+". "+strBak[i]);
          }
        }
        
        // 利用拷贝删除数组某个位置某个元素
        public void removeElment(){
          System.out.println("*************************************");
          // 删除数组中间的数,本质上还是拷贝,例如删掉下标1的内容”黄泽雨“
          System.arraycopy(str, 2, str, 1, 2); //将2、3拷贝覆盖1、2
          str[str.length-1] = null; //将多出的3改为null
          for(int i=0; i<str.length; i++) {
            System.out.println(i+". "+str[i]);
          }
        }
        
        // 封装一个利用拷贝删除数组的工具
        public String[] removeElmentTool(String[] array, int index){
          System.arraycopy(array, index+1, array, index, array.length-index-1);
          array[array.length-1] = null;
          for(int i=0; i<array.length; i++) {
            System.out.println(i+". "+array[i]);
          }
          return array;
        }
        public void testRemoveElmentTool() {
          System.out.println("*************************************");
          removeElmentTool(str2, 1);
        }
        
        // 扩容数组,本质上是创建一个更大的数组,将原数组数据拷贝到更大的数组中
        public void extendRange() {
          System.out.println("*************************************");
          String[] arrayExtend = new String[str3.length+3]; //创建一个比str3数组大3的数组
          System.arraycopy(str3, 0, arrayExtend, 0, str3.length); //将str3数组数据拷贝到arrayExtend数组中去
          for(int i=0; i<arrayExtend.length; i++) {
            System.out.println(i+". "+arrayExtend[i]);
          }
        }
        
        // 数组插入数据
        public void insertArray(){
          System.out.println("*************************************");
          String[] arrayExtend2 = new String[str3.length+3];
          System.arraycopy(str3, 0, arrayExtend2, 0, str3.length); //将str3数据拷贝到更大的数组arrayExtend2内
          System.arraycopy(str4, 0, arrayExtend2, 1, 1); //将str4中的下标为0的数据插入到arrayExtend2的下标1中
          System.arraycopy(str3, 1, arrayExtend2, 2, str3.length-1); //将被覆盖的数据重新拷贝回来,完成插入数据
          for(int i=0; i<arrayExtend2.length; i++) {
            System.out.println(i+". "+arrayExtend2[i]);
          }
        }
      }
    • java.util.Arrays类:JDK提供的java.util.Arrays类,包含了常用的数组操作,方便日常开发。Arrays类包含了:排序、查找、填充、打印内容等常见的操作。
      package me.hzyis.test;
      import java.util.Arrays;
      public class Test {
        public static void main(String[] args) {
          int[] a = {1,2,3};
          System.out.println(a); //输出string和a的哈希值
          System.out.println(Arrays.toString(a)); //输出数组内容
          
          System.out.println("*****************************");
          int[] b = {100,50,30,200,10};
          System.out.println(Arrays.toString(b));
          Arrays.sort(b); //从小到大排序
          System.out.println(Arrays.toString(b));
          
          int[] c = {100,50,30,200,10};
          System.out.println("30的索引位置:"+Arrays.binarySearch(c, 30)); //查找30所在的索引位置
          System.out.println("-30的索引位置:"+Arrays.binarySearch(c, -30)); //如果查找的值不存在则返回负值
        }
      }
    • 多维数组:多维数组可以看成以数组为元素的数组(数组套数组),可以有二维、三维、甚至更多维数组(套多层数组)。
      • 二维数组:
        package me.hzyis.test;
        public class Test {
          public static void main(String[] args) {
            int[] arr01 = new int[3]; //一维int类型数组
            Car[] cars = new Car[3]; //一维引用类型数组
            
            int[][] arr02 = new int[3][]; //二维int类型数组,数组套数组
            arr02[0] = new int[] {10,20}; //
            arr02[1] = new int[] {30,40};
            arr02[2] = new int[] {50,60,70};
            System.out.println(arr02[2][2]);
            
            // 静态初始化二维数组
            int[][] arr03 = {
                {10,20},
                {100,200},
                {1000,2000}
            };
            System.out.println(arr03[2][1]);
          }
        }
        class Car{}

    • 数组存储表格数据:表格数据模型是计算机世界最普遍的模型,可以说互联网上看到的所有数据本质上都是“表格”,无非是表格之间互相套用。
      package me.hzyis.test;
      import java.util.Arrays;
      public class Test {
        public static void main(String[] args) {
          // 此处001本质不是Object对象,编译器会把基本数据类型“自动装箱”成包装类对象
          Object[] emp1 = {001,"黄泽风",20,"学员"};
          Object[] emp2 = {002,"黄泽雨",21,"学员"};
          Object[] emp3 = {003,"黄泽雷",22,"学员"};
          Object[] emp4 = {004,"黄泽电",23,"学员"};
          
          Object[][] tableData = new Object[4][];
          tableData[0] = emp1;
          tableData[1] = emp2;
          tableData[2] = emp3;
          tableData[3] = emp4;
          for(Object[] temp:tableData) {
            System.out.println(Arrays.toString(temp));
          }
        }
      }