数组

数组

什么是数组

数组是相同类型数据的有序集合

数组描述的是相同类型的若干个数据,按照一定的先后顺序排列组合在一起

每一个数据称作为一个数组元素,通过下标可以访问它们

为什么需要数组

假如需要创建100个int类型的对象,那我们不是需要100个int类型对象,操作繁琐且不简洁,而数组可以存储它们

声明数组

数据类型[] 数组名; //首选
数据类型 数组名[]; //其次 这个是由于是来自c语言,建议不要使用这个

创建数组

数据类型[] 数组名=new 数据类型[数组长度]

数组通过索引(下标)来访问它的,索引从0开始

获取长度:数组名.length

public static void main(String[] args) {
        int[] nums=new int[4]; //创建一个数组
        nums[0]=1;  //通过下标来存储值,因为数组下标从0开始,总共长度4,说明数组下标为4-1=3
        nums[1]=2;
        nums[2]=3;
        nums[3]=4;
    	//循环遍历数组的值
        for (int i = 0; i < nums.length ; i++) { //nums.length获取数组的长度
            System.out.println(nums[i]); //访问数组的值,也是通过下标来访问
            //i的值为0,数组长度为4,i要小于4,所以只有0,1,2,3
            //假如有一个没有赋值 int的默认是为0
            //不懂默认值 https://www.cnblogs.com/ShuaiStudy/p/13969156.html
        }
    }

内存分析

堆:存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用

栈:存放基本类型(包含这个基本类型的具体数值),引用对象的变量(会存放这个引用在堆里面的具体地址)

方法区:可以被所有的线程共享,包含所有的class和static变量(暂时了解一下即可)

数组的初始化

  1. 静态初始化
int[] array={1,2,3,4}
  1. 动态初始化
int[] array=new int[2]
    array[0]=1;
	array[1]=2;
  1. 数组默认初始化

数组的初始化默认值:https://www.cnblogs.com/ShuaiStudy/p/13969156.html

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量的方式别隐式初始化

数组的四个基本特点

  1. 其长度是确定的,数组一旦被创建,它的大小不可以被改变
  2. 其元素必须是相同类型,不能又混合类型
  3. 数组元素可以任何数据类型
  4. 数组变量属引用类型,数组可以看成一个对象,数组的每个元素相当于该对象的成员变量
  5. 数组本身就是对象,对象是在堆中,数组的对象本身是在堆中的

下标越界

int[] array=new int[2];
array[2]=2; //由于数组的下标从0开始,所有下标只有0和1,当给它这个数组的下标超过本身下标,就会报错

ArrayIndexOutOfBoundsException:当看到这个错误就是数组下标越界了

数组的使用

for循环和foreach循环

public static void main(String[] args) {
        int[] nums=new int[4];
        nums[0]=1;
        nums[1]=2;
        nums[2]=3;
        nums[3]=4;
    //输出数组的值
        for (int i = 0; i < nums.length ; i++) {
            System.out.println(nums[i]);
        }
    //输出数组的值
        for (int num : nums) {
            System.out.println(num);
        }
    }

数组做为参数

//输出数组的值
static void out(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
public static void main(String[] args) {
        int[] nums=new int[4];
        nums[0]=1;
        nums[1]=2;
        nums[2]=3;
        nums[3]=4;
        out(nums);
    }

数组做为返回值

//反转数组
    static int[] numbers(int[] array){
        int[] arrays=new int[array.length];
        for (int i = 0,j=arrays.length-1;i <array.length ; i++,j--) {
            arrays[j]=array[i];
        }
        return arrays;
    }
public static void main(String[] args) {
        int[] nums=new int[4];
        nums[0]=1;
        nums[1]=2;
        nums[2]=3;
        nums[3]=4;
        int[] numbers=numbers(nums);
    //前面定义了一个输出数组的方法out(int[] array)
        out(numbers);
    }

多维数组

多维数组可以看成数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组

二维数组

语法

//数据类型[][] 变量名=new 数据类型[m][n];
//m表示这个二维数组有多少个数组
//n表示每一个一维数组的元素个数
    int[][] arr=new int[3][2];
//定义了一个二维数组arr
//这个二维数组有3个一维数组,名称是ar[0],arr[1],arr[2]
//每个一维数组有2个元素,可以通过arr[m][n]来获取

多维数组的实例:

public static void main(String[] args) {
        int a[][]={{1,2},{2,3}}; //创建一个多维数组
        //{1,2} 这个下标为0 {2,3} 这个下标为1
        //a[0][0] 前面那个0为数组的下标为0 第二个0是取得值是第一个
        System.out.println(a[0][0]);
        System.out.println(a[0][1]);
        System.out.println(a[1][0]);
        //a的数组只有两个长度,因为他们{1,2}是一个整体
        System.out.println(a.length); //2
        //a的0下标里面有两个数  
        System.out.println(a[0].length);//2
        //循环外围的两个整体
        for (int i = 0; i <a.length ; i++) {
            //循环整体里面的两个数
            for (int j = 0; j < a[i].length; j++) {
                System.out.println(a[i][j]); //取出整体里面的值
            }
        }
    }

Arrays数组

Arrays.sort() 升序排列

Arrays.toString() 数组以字符串的形式输出

Arrays.equals() 比较两个数组的值是否相同

Arrays.binarySearch() 使用二进制搜索算法搜索指定值的指定字节数组

Arrays.copyOfRange() 将指定数组的指定范围复制

int[] arrays=new int[]{1,2,7,4,68,5,4};
//把数组转换成字符串输出
System.out.println(Arrays.toString(arrays));
//将数组从小到大排序
Arrays.sort(arrays);
//输出排序好的数组
//注意点
//如果是数值,sort默认按照升序从小到大
//如果是字符串,sort默认按照字母的升序
System.out.println(Arrays.toString(arrays));
int[] arrays1={1,2,7,4,68,5,4};
Arrays.sort(arrays1);
//比较数组的值是否相等
//两个数组以相同的顺序包含相同的元素,则它们是相等的
//如果两个数组引用都是null,则它们被认为是相等的
System.out.println(Arrays.equals(arrays,arrays1));
Arrays.sort(arrays1);
//a - 要搜索的数组
//key - 要搜索的值
//使用二进制搜索算法搜索指定值的指定字节数组
// 在进行此调用之前,数组必须按照sort(byte[])方法进行排序。
// 如果没有排序,结果是未定义的。 如果数组包含具有指定值的多个元素,则不能保证将找到哪个元素。
System.out.println(Arrays.binarySearch(arrays1,68));
//将指定数组的指定范围复制到新数组中
//from - 要复制的范围的初始索引(包括)
//to - 要复制的范围的最终索引,排他。 (该索引可能位于数组之外)
int[] arrays2=Arrays.copyOfRange(arrays1, 0, 4);
System.out.println(Arrays.toString(arrays2));

冒泡排序

它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成

算法

冒泡排序算法的原理如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数
  3. 针对所有的元素重复以上的步骤,除了最后一个
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
public static void main(String[] args) {
        //创建一个数组
        int[] arr=new int[]{2,5,1,3,2};
        //调用下面写的静态方法 传入数组的参数 并创建一个数组接受它
        int[] arr1=sort(arr);
        //通过Arrays的数组工具类来给数组输出值
        System.out.println(Arrays.toString(arr1));
    }
    //冒泡排序的方法(降序 从大到小)
    static int[] sort(int[] arr){
        //循环比较的次数 五个数只需要比较四次
        for (int i = 0; i < arr.length-1; i++) {
            //循环比较相邻两个数的大小 把大的数放到前面 小的数在后面
            for (int j = 0; j <arr.length-1-i ; j++) { //arr.length-1-i 每次数组最后的值都是最小的,就可以减去一次循环,没必要比了
                //判断相邻后面的数比前面的数大的时候
                if (arr[j+1]>arr[j]){
                    //创建一个临时变量,把小的给temp
                    int temp=arr[j];
                    //把大的给到前面
                    arr[j]=arr[j+1];
                    //把小的temp给到后面
                    arr[j+1]=temp;
                }
            }
        }
        //返回排序好的数组
        return arr;
    }

稀疏数组

稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组

刚说到稀疏数组是一种压缩后的数组,为什么要进行压缩存储呢?

  • 原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据却少之又少
  • 压缩存储可以节省存储空间以避免资源的不必要的浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率

把二维数组变成稀疏数组

步骤:

  1. 创建一个二维数组

  2. //数据类型[][] 变量名=new 数据类型[m][n];
    //m表示这个二维数组有多少个数组
    //n表示每一个一维数组的元素个数
    
  3. 随便给几个坐标附上附上值,下标从0开始

  4. 打印出这个数组的所有值(看看有哪些)

  5. 获取这个数组里面的有效值,不然所有的值都为0

  6. 创建一个稀疏数组(多少个数组是有效值+1,长度则是3)

  7. 判断不为0的数,给这个稀疏数组赋值

  8. 输出稀疏数组

把稀疏数组变成二维数组

步骤:

  1. 创建一个稀疏数组(它的长度为二维数组的行和列)

  2. //数据类型[][] 变量名=new 数据类型[m][n];
    //m表示这个二维数组有多少个数组
    //n表示每一个一维数组的元素个数
    
  3. 循环把有效值赋值给二维数组的坐标上(坐标为稀疏数组的行和列)

  4. 输出还原的二维数组

完整代码

public static void main(String[] args) {
    //创建一个二维数组 11*11
    int[][] arr=new int[11][11];
    //给数组的第二行的第三个数赋值1
    arr[1][2]=1;
    //给数组的第三行的第四个数赋值2
    arr[2][3]=2;
    System.out.println("输出原始数组");
    //循环输出数组里面的值
    for (int[] ints : arr) {
        for (int anInt : ints) {
            System.out.print(anInt+"\t");
        }
        //当循环出一个数组时换行
        System.out.println();
    }
    //转换为稀疏数组保存
    //获取有效值的个数
    int sum=0;
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            if(arr[i][j]!=0){
                sum++;
            }
        }
    }
    System.out.println("有效值为"+sum);
    //创建一个稀疏数组的数组 sum+1确定有多少个有效数需要存放(包括二维数组的行和列)
    int[][] arr1=new int[sum+1][3];
    //给数组的第一行的第一个数赋值11
    arr1[0][0]=11;
    //给数组的第一行的第二个数赋值11
    arr1[0][1]=11;
    //给数组的第一行的第三个数赋值
    arr1[0][2]=sum+1;
    //创建一个临时的变量 计算有多少个有效值的坐标赋值
    int count=0;
    for (int i = 0; i < arr.length; i++) {
        //循环输出arr里面的值
        for (int j = 0; j < arr.length; j++) {
            if(arr[i][j]!=0){
                count++;
                //给数组的第count行的第一个数赋值i
                arr1[count][0]=i;
                //给数组的第count行的第一个数赋值j
                arr1[count][1]=j;
                //给数组的第count行的第一个数赋值arr[i][j]
                arr1[count][2]=arr[i][j];
            }
        }
    }
    //输出获取有效值的数组
    System.out.println("稀疏数组:");
    System.out.println("行\t列\t有效值");
    for (int i = 0; i < arr1.length; i++) {
        for (int j = 0; j <arr1.length ; j++) {
            System.out.print(arr1[i][j]+"\t");
        }
        System.out.println();
    }
    //把稀疏数组还原成二维数组
    //给创建的数组给它赋值行和列
    int[][] arr3=new int[arr1[0][0]][arr1[0][1]];
    //值从1开始循环 不然下标的坐标越界
    for (int i = 1; i < arr1.length; i++) {
        //把arr1的[i][2]值赋给arr3[arr1[i][0]][arr1[i][1]]的坐标上
        arr3[arr1[i][0]][arr1[i][1]]=arr1[i][2];
    }
    //循环输出数组里面的值
    System.out.println("还原的二维数组:");
    for (int[] ints : arr3) {
        for (int anInt : ints) {
            System.out.print(anInt+"\t");
        }
        //当循环出一个数组时换行
        System.out.println();
    }
}
posted @ 2020-11-18 14:58  博客帅帅  阅读(98)  评论(0)    收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css