Java学习笔记-Day3

Part4:数组操作

数组的声明和创建

数组的四个基本特点

  1. 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的;
  2. 其元素必须是相同类型,不允许出现混合类型;
  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型;
  4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量,数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.zhou.arr;

// 数组的声明和创建
public class Demo01 {
public static void main(String[] args) {
// 动态声明,默认值为0
int[] arr1; // 声明
arr1 = new int[10]; // 创建

int[] arr2 = new int[10]; // 声明和创建一起

for (int i = 0; i < arr1.length; i++) {
arr1[i] = i+1;
arr2[i] = i;
}

// 静态声明
int[] arr3 = {1,2,3,4,5,6,7,8,9,10};

// 输出数组
for (int i = 0; i < arr1.length; i++) {
System.out.println("arr1[" + "]:" + arr1[i]);
// System.out.println("arr2[" + "]:" + arr2[i]);
// System.out.println("arr3[" + "]:" + arr3[i]);
}

}

}

内存分析

参考博客:https://blog.csdn.net/qq_44038822/article/details/108918945

在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:

Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行管理。

JVM内存的划分有五片:

  1. 寄存器——寄存命令所在的地址;
  2. 本地方法区(栈)——和栈相同但是用于执行本地方法;
  3. 方法区——存储类的信息、常量、静态变量、编译后的代码;
  4. 栈内存——存储局部变量;
  5. 堆内存——存储对象、数组。

比如主函数里的语句int[] arr=new int[3];在内存中是怎么被定义的:

主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值。实体(对象)创建在堆里,在堆里首先通过new关键字开辟一个空间,然后给这个实体分配一个内存地址(内存在存储数据的时候都是通过地址来体现的,地址是一块连续的二进制)。数组都有一个索引,数组这个实体(对象arr)在堆内存中产生之后每一个空间都会进行默认的初始化(数组默认为0),不同的类型初始化的值不一样。

在堆和栈里分别创建了变量和实体:

那么堆和栈是怎么联系起来的呢?

我们刚刚说过给堆分配了一个地址,把堆的地址赋给arr,arr就通过地址指向了数组。所以arr想操纵数组时,就通过地址,而不是直接把实体都赋给它。这种我们不再叫他基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。(可以理解为c或c++的指针,Java成长自c++和c++很像,优化了c++)

Arrays类

数组的工具类:java.util.Arrays

由于数组对象本身没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作。

Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类目进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)。

  • Arrays类具有以下常用功能:

    • 给数组赋值:通过fill方法;

    • 对数组排序:通过sort方法,默认升序;

    • 比较数组:通过equals方法比较数组中元素值是否相等;

    • 查找数组元素:通过binarySearch方法能对排序号的数组进行二分法查找操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.zhou.arr;

import java.util.Arrays;

// Arrays类的使用
public class Demo02 {
public static void main(String[] args) {
int[] nums = {10, 9, 1, 2, 3, 4, 5, 6, 7, 8};

System.out.println(nums); // 打印结果:[I@1b6d3586

// 打印数组元素 Arrays.toString
System.out.println(Arrays.toString(nums));
System.out.println("================================");
// for each 循环,打印数组元素,print不会换行
System.out.print("[");
for (int i : nums) {
if (i != nums[nums.length - 1]) {
System.out.print(i + ", ");
} else {
System.out.println(i + "]");
}
}
System.out.println("================================");

// 对数组进行排序,升序
Arrays.sort(nums); //Arrays类只是提供了默认的升序排列,没有提供相应的降序排列方法。
System.out.println(Arrays.toString(nums));
System.out.println("================================");

// 降序:先升序再降序
Arrays.sort(nums);
int n = nums.length;
int[] tmp = new int[n];
for (int i = 0; i < n; i++) {
tmp[i] = nums[n-1-i];
}
System.out.println(Arrays.toString(tmp));
nums = tmp;
System.out.println(Arrays.toString(nums));

// Arrays.sort(nums);
// for (int i=0,j=nums.length-1; i<j; i++,j--){
// int tmp = nums[i];
// nums[i] = nums[j];
// nums[j] = tmp;
// }
// System.out.println(Arrays.toString(nums));
}
}

稀疏数组

在矩阵(数组)中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.zhou.arr;

import java.util.Arrays;

// 稀疏数组的压缩存储
// 将n*m稀疏数组用N*3的数组存储每个非0元素的地址和值(行、列、值)
/*
第0行 n m 非0元素个数
第1行 第1个非0元素的行号 第1个非0元素的列号 第1个非0元素的值
第2行 第2个非0元素的行号 第2个非0元素的列号 第2个非0元素的值
第3行 第3个非0元素的行号 第3个非0元素的列号 第3个非0元素的值
...
第N行 第N个非0元素的行号 第N个非0元素的列号 第N个非0元素的值
*/
public class Demo03 {
public static void main(String[] args) {
int[][] nums = new int[10][10];
nums[2][3] = 1; // 第2行第3列,行号和列号从0开始
nums[5][6] = 2;
nums[9][9] = 3;

// 打印稀疏数组
for (int i = 0; i < nums.length; i++) {
System.out.println(Arrays.toString(nums[i]));
}
System.out.println("===============================");

// 压缩存储稀疏数组
int n = nums.length;
int m = nums[0].length;
int N = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (nums[i][j] != 0) {
N++;
}
}
}
System.out.println("N="+N);
System.out.println("===============================");
int[][] arr = new int[N+1][3];
N = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (nums[i][j] != 0) {
N++;
arr[N][0] = i;
arr[N][1] = j;
arr[N][2] = nums[i][j];
}
}
}
arr[0][0] = n;
arr[0][1] = m;
arr[0][2] = N;
// 打印
for (int i = 0; i < N+1; i++) {
System.out.println(Arrays.toString(arr[i]));
}
}

}

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 归一
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信