java数组(数组的声明、三种初始化方式及内存分析、多维数组、Arrays类、冒泡排序、稀疏数组)

 

Java基础学习笔记4——数组

  • 数组是相同类型数据的有序集合
  • 相同类型的数据按照一定先后顺序排列,每个数据有一个下标,可以通过下标来查找数据,下标从0开始
  • 数组的类型可以是任意类型,包括基本类型和引用类型
  • 数组的变量本身是引用类型,数组也可以看成是对象,数组对象本身是在堆内存中

数组的声明

  • 声明语法
//数据类型[] 数据名 = new 数据类型[数组长度]
int[] arr = new int[10]; 
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
arr[5] = 6;
arr[6] = 7;
arr[7] = 8;
arr[8] = 9;
arr[9] = 10;

下标

0

1

2

3

4

5

6

7

8

9

数据

1

2

3

4

5

6

7

8

9

10

  • 数组元素通过下标来访问
  • 数组的长度是创建时就定义好的不可以改变
  • 获取数组长度的方法:arr.length
  • 数组边界
  • 数组存在一个下标的合法区间[0,length-1],如果越界就会报错
  • 遍历数组
  • 使用for循环遍历
int[] arr = new int[10]; 
for(int i = 0 ; i < arr.length-1 ; i++){
    System.out.println(arr[i]);
}
  • 使用for-each循环(增强for循环)
int[] arr = new int[10]; 
for(int a ; arr){
    System.out.println(a);
}

 

 

三种初始化方式及内存分析

  1. 初始化方式
  • 静态初始化:在数组创建时就定义好数组内的数据
int[] a = {1,2,3,4,5,6,7,8,9};
  • 动态初始化:数组创建之后在一个个去定义数据
int[] arr = new int[10]; 
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
arr[5] = 6;
arr[6] = 7;
arr[7] = 8;
arr[8] = 9;
arr[9] = 10;
  • 默认初始化:数组是引用类型,因此在创建好,分配了内存空间之后就会被隐式初始化,数据值为相应数据类型的默认值
  1. 内存分析
int[] a;//这一步时栈内存出现了一个名为a的内存空间
a = new int[10];//在堆内存中创建了一个内存空间存储信息,并生成了一个内存地址赋给栈内存中的a,之后访问a时就通过内存地址找到堆内存中的数据

 

多维数组

  • 多维可以看做数组的数组,就是在数组里面存放数组
  • 以二维数组为例
int[][] arr = new int[4][2];//这就是一个二维数组的定义,可以看做一个四行两列的数组
int[][] arr = {{1,2},{3,4},{5,6},{7,8}};//这个数组就和上面一样

arr

arr[] []

arr[] [0]

arr[] [1]

arr[0] []

1 (arr[0] [0])

2 (arr[0] [1])

arr[1] []

3 (arr[1] [0])

4 (arr[1] [1])

arr[2] []

5 (arr[2] [0])

6 (arr[2] [1])

arr[3] []

7 (arr[3] [0])

8 (arr[3] [1])

 

Arrays类

  • 数组的工具类java.util.Arrays
  • java提供的操作数组的方法类,有很多方法可以查看API帮助文档
  • Arrays的类但是通过static修饰的,可以直接通过类名进行调用
int[] arr = {2,1,4,3,5};

System.out.println(Arrays.toString(arr));//toString用于输出数组
//输出样式[2,1,4,3,5]


Arrays.sort(arr)//sort排序方法
System.out.println(Arrays.toString(arr));//sort排序方法
//输出样式[1,2,3,4,5]

 

冒泡排序

  • 冒泡排序是作为出名的排序算法之一
  • 冒泡排序比较简单两层循环,外层冒泡轮数,里层比较,冒泡排序时间复杂度为O(n2)
int temp = 0;//临时变量
//外层循环,控制还要排序几次
for(int i = 0 ; i < arr.length-1 ; i++){
    //比较两个数,谁大谁向前走
    for(int j = 0 ; j < arr.length-1-i ; j++){
        if(arr[j+1]>arr[j]){
            temp = arr[j];
            arr[i] = arr[j+1];
            arr[i+1] = temp;
        }
    }
}

 

稀疏数组

  • 一种数组的压缩方式,可以节省空间
  • 如果一个二维数组中存储的数据有大量重复就可以用稀疏数组的方法进行压缩
  • 以五子棋游戏为例,游戏中途退出,保存棋盘
//棋盘原始数组
0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0
0 0 2 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 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代表黑棋 2代表白棋 棋盘十一行十一列
//棋盘的原始数组就是
int[][] arr = new int[11][11];
arr[1][1] = 1;
arr[2][2] = 2;
  • 棋盘的大多数都是没有意义的数值0
  • 稀疏数组的处理方式
  • 记录数组有几行几列,有多少不同的值,值的位置
  • 把它记录在一个规模较小的数组中,从而达到缩小规模的目的
//棋盘稀疏数组
11 11 2 //第一行记录原始数组大小和有效数字
1  1  1 //第一个有效数字的位置与数值
2  2  2 //第二个有效数字的位置与数值
  • 转换方法(无意义数值为0的)
//原始棋盘信息
int[][] arr = new int[11][11];
arr[1][1] = 1;
arr[2][2] = 2;
//输出原始棋盘数组
for(int[] ar:arr){
    for(int a:ar){
        System.out.print(a+"\t");
    }
    System.out.println();//换行
}

//输出的原始棋盘数组
0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0
0 0 2 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 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
    
//获取有效值个数
int sum = 0;
for(int[] ar:arr){
    for(int a:ar){
       if(a!=0){
           sum++;
       }
    }
}
//创建一个稀疏数组
int[][] arr2 = new int[sum+1][3];
arr2[0][0] = 11;
arr2[0][1] = 11;
arr2[0][2] = sum;