【KuangStudy】Java数组详解

数组详解

什么是数组

  • 数组是相同类型数据的有序集合
  • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
  • 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们

数组的声明和创建

  • 首先必须**声明*8数组变量,才能在程序中使用数组,下面是声明数组变量的语法:
dataType[] arrayRefVar;//首选的方法
dataType arrayRefVar[];//效果相同,但不是首选方法(C&C++风格)
  • Java语言使用new操作符来创建数组(开辟存储空间),语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
  • 数组的元素是通过索引访问的,数组索引从0开始

  • 获取数组的长度

int[] array=new int[10];//创建一个长度为10的int型数组array
array[0]=1;//数组array的第一个元素赋值为1
array[9]=10;//数组array的第十个元素赋值为10
int length=array.length;//10

三种初始化及内存分析

Java内存分析

    • 存放new的对象和数组
    • 可以被所有的线程共享,不会存放别的对象引用
    • 存放基本变量类型(会包含这个基本类型的具体数值)
    • 引用对象的变量(会存放这个引用在堆里面的具体地址)
  • 方法区
    • 可以被所有的线程共享
    • 包含了所有的class和static变量

三种初始化

  • 静态初始化
int[] array1= {1,2,3};
  • 动态初始化
int[] array2=new int[10];
array2[0]=1;//后期赋值
  • 数组的默认初始化
    • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化(0或0.0或null)

下标越界及小结

  • 数组的四个基本特点
    • 其长度是固定的,数组一旦被创建,它的大小就是不可以被改变的
    • 其元素必须是相同类型,不允许出现混合类型
    • 数组中的元素可以是任何数据类型,包括基本类型和引用类型
    • 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量
    • 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的
  • 数组边界
    • 下标的合法区间[0,length-1],如果越界就会报错
    • ArrayIndexOutOfBoundsException:数组下标越界异常
  • 小结:
    • 数组是相同数据类型(数据类型可以为任意类型)的有序集合
    • 数组也是对象。数组元素相当于对象的成员变量
    • 数组长度是确定的,不可变的。如果越界,则报ArrayIndexOutOfBounds

数组的使用

普通的For循环

public class Demo01 {
    public static void main(String[] args) {
        int[] array= {1,2,3,4,5};
        //遍历输出数组元素
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();
        System.out.println("==================");
        //计算所有元素的和
        int sum=0;
        for (int i = 0; i < array.length; i++) {
            sum+=array[i];
        }
        System.out.println("sum="+sum);
        System.out.println("==================");
        //查找最大元素
        int max=array[0];
        for (int i = 1; i < array.length; i++) {
            if(max<array[i])max=array[i];
        }
        System.out.print("max="+max);
    }
}
/*输出结果
1 2 3 4 5 
==================
sum=15
==================
max=5
*/

For-Each循环

public class Demo01 {
    public static void main(String[] args) {
        int[] array= {1,2,3,4,5};
        for (int i : array) {//无法获取下标,适合遍历输出
            System.out.print(i+" ");
        }
    }
}
/*输出结果
1 2 3 4 5 
*/

数组作为方法的参数

public class Demo01 {
    public static void main(String[] args) {
        int[] array= {1,2,3,4,5};
        System.out.print("sum="+sum(array));//调用sum方法
    }
    public static int sum(int[] array){
        int sum=0;
        for (int i = 0; i < array.length; i++) {
            sum+=array[i];
        }
        return sum;
    }
}
/*输出结果
sum=15
*/

数组作为方法的返回值

public class Demo01 {
    public static void main(String[] args) {
        int[] array= {1,2,3,4,5};
        print(reverse(array));//输出翻转后的array
    }
    public static int[] reverse(int[] array){//翻转array,返回reverse数组
        int[] reverse=new int[array.length];
        for (int i = 0; i < array.length; i++) {
            reverse[i]=array[array.length-i-1];
        }
        return reverse;
    }
    public static void print(int[] array){//遍历输出array
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
    }
}
/*输出结果
5 4 3 2 1 
*/

二维数组

  • 多维数组可以看成是数组的数组, 比如二维数组就是一个特殊的一维数组,它的每一个元素都是一个一维数组
  • 二维数组
int[][] a1=new int[2][5];
int a2[][]=new int[2][5];
  • 解析:以上二维数组可以看成是一个两行五列的数组
  • 多维数组的遍历
public class Demo01 {
    public static void main(String[] args) {
        int[][] array={{1,3,5,7,9},{0,2,4,6,8}};
        print(array);
    }
    public static void print(int[][] array){
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {//遍历一维数组array[i]
                System.out.print(array[i][j]+" ");
            }
            System.out.println();//遍历输出一维数组array[i]后换行
        }
    }
}
/*输出结果
1 3 5 7 9 
0 2 4 6 8 
*/

Arrays类讲解

  • 数组的工具类java.util.Arrays
  • 由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
  • 查看JDK帮助文档
  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而无需使用对象来调用
  • 常用功能:
    • 给数组赋值:fill
    • 对数组排序:sort(升序)
    • 比较数组是否相等:equals
    • 查找数组元素:binarySearch(二分查找)
public class Demo01 {
    public static void main(String[] args) {
        int[] array={54,34,3,23,234,5,57,86};
        //输出array对象的HashCode
        System.out.println("输出array对象的HashCode:");
        System.out.println(array);
        //输出array
        System.out.println("输出array:");
        System.out.println(Arrays.toString(array));
        //升序排序array
        System.out.println("升序排序array:");
        Arrays.sort(array);
        System.out.println(Arrays.toString(array));
        //给array数组全部赋值为0
        System.out.println("给array数组全部赋值为0:");
        Arrays.fill(array,0);
        System.out.println(Arrays.toString(array));
        //给array数组下标为2~6的元素赋值为1
        System.out.println("给array数组下标为2~6的元素赋值为1:");
        Arrays.fill(array,2,7,1);//下标范围[2,7)
        System.out.println(Arrays.toString(array));
    }
}
/*输出结果
输出array对象的HashCode:
[I@1b6d3586
输出array:
[54, 34, 3, 23, 234, 5, 57, 86]
升序排序array:
[3, 5, 23, 34, 54, 57, 86, 234]
给array数组全部赋值为0:
[0, 0, 0, 0, 0, 0, 0, 0]
给array数组下标为2~6的元素赋值为1:
[0, 0, 1, 1, 1, 1, 1, 0]
*/

冒泡排序(升序)

  1. 遍历数组,比较数组中两个相邻的元素,如果前一个数比后一个数大,就交换它们的位置
  2. 经过一轮遍历会将最大的数交换到数组的最后
  3. 从头开始遍历,但不会比较到最后一个数……经过一轮遍历会将第二大的数交换到数组的最后
  4. 从头开始遍历,但不会比较到最后两个数……经过一轮遍历会将第三大的数交换到数组的最后
  5. 依次循环直到结束……
public class Demo01 {
    public static void main(String[] args) {
        int[] array={54,34,3,23,234,5,57,86};
        sort(array);
        System.out.println(Arrays.toString(array));
    }
    //冒泡排序
    public static void sort(int[] array) {
        int t;
        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length-1-i; j++) {
                if(array[j]>array[j+1]){
                    t=array[j];
                    array[j]=array[j+1];
                    array[j+1]=t;
                }
            }
        }
    }
}
/*输出结果
[3, 5, 23, 34, 54, 57, 86, 234]
*/

稀疏数组(SparseArray)

  • 当一个数组中大部分元素为0,或者为同一值时,可以使用稀疏数组来保存该数组
  • 稀疏数组的处理方式:
    • 记录数组一共有几行几列,有多少个不同数值
    • 把具有不同数值的元素的行、列、数值记录在一个小规模的数组中,从而缩小程序的规模
  • 稀疏数组格式:
SparseArray第0列第1列第2列
第0行总行数总列数默认值
第1行行数1列数1数值1
第2行行数2列数2数值2
第3行行数3列数3数值3
……………………
  • 案例:将一个11X11的二维数组转换成稀疏数组,并将稀疏数组以原数组的形式输出
public class Demo01 {
    public static void main(String[] args) {
        int[][] array1=new int[11][11];
        array1[3][4]=1;
        array1[5][6]=1;
        print(array1);
        System.out.println("===================");
        int[][] array2=sparse(array1,0);
        print(array2);
        System.out.println("===================");
        printSparse(array2);
    }
    //转换成稀疏数组
    public static int[][] sparse(int[][] array,int x){//接收原数组以及默认值
        int n=0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                if(array[i][j]!=x){
                    n++;//记录不同值的个数,以确定新建的稀疏数组的行数
                }
            }
        }
        int[][] sparse=new int[n+1][3];
        sparse[0][0]=array.length;
        sparse[0][1]=array[0].length;
        sparse[0][2]=x;//第一行存储数组基本信息
        int k=1;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                if(array[i][j]!=x){
                    sparse[k][0]=i;
                    sparse[k][1]=j;
                    sparse[k][2]=array[i][j];
                    k++;//将不同值的行标、列标和数值逐个存储至稀疏数组
                }
            }
        }
        return sparse;//返回生成的稀疏数组
    }
    //输出数组
    public static void print(int[][] array){
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
    }
    //将稀疏数组还原输出
    public static void printSparse(int[][] array){
        int k=1;
        for (int i = 0; i < array[0][0]; i++) {
            for (int j = 0; j < array[0][1]; j++) {
                if(k<array.length&&i==array[k][0]&&j==array[k][1]){//利用逻辑运算符的短路特性,当k>=array.length时不执行后续判断,避免了下标越界问题
                    System.out.print(array[k][2]+" ");
                    k++;//稀疏数组存放不同值的顺序与遍历顺序相同,因此可逐个定位并输出
                }else {
                    System.out.print(array[0][2]+" ");//否则输出默认值
                }
            }
            System.out.println();
        }
    }
}
/*输出结果
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
===================
11 11 0 
3 4 1 
5 6 1 
===================
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值