原理与内存存储:内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。 Java虚拟机要运行程序,必须要对内存进行空间的分配和管理
区域名称 | 作用 |
寄存器 | CPU使用,开发无关 |
本地方法栈 | JVM使用操作系统功能时使用,开发无关 |
方法区 | 存储可以运行的class文件 |
堆内存 | 存储对象或者数组,new来创建的,都存储在堆内存 |
方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行 |
1、虚拟机栈(Stack):存放的是方法中的局部变量,只在作用域有效,存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
2、堆(Heap):存储new出来的所有对象,比如integer对象,数组对象,实例对象等。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java 虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配,不是“绝对”的。
3、方法区(Method Area):存储.class相关信息,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,public static void main(String[] args){}。
![](https://i-blog.csdnimg.cn/blog_migrate/0198f91aa112ec16420b5176957e69e4.png)
一、一维数组
数组对于每一门编程语言来说都是重要的数据结构之一
Java 语言中提供的数组是用来存储固定大小的同类型元素。
声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量,下标从0开始,若不赋值,那么默认为0。
1.1 创建数组
动态初始化:dataType[] arrayRefVar = new dataType[arraySize];
静态初始化:dataType[] arrayRefVar = {value0, value1, ..., valuek};
1.2 *数组的基本操作*
public class TestArray {
public static void main(String[] args) {
double[] myList = {1.9, 2.9, 3.4, 3.5};//1、静态初始化
//2、动态初始化:存储3个整数的数组容器 int[] arr = new int[3];
// 3、打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
}
/*
1.9
2.9
3.4
3.5
*/
// 4、计算所有元素的总和
double total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println("Total is " + total);
//Total is 11.7
// 5、查找最大元素
double max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max) max = myList[i];
}
System.out.println("Max is " + max);
//Max is 3.5
//6、For-Each 循环或者加强型循环
for (double element: myList) {
System.out.println(element);
}
/*
1.9
2.9
3.4
3.5
*/
}
}
//数组翻转
public class ArrayReverse {
//编写一个 main 方法
public static void main(String[] args) {
//定义数组
int[] arr = {1, 2, 3, 4, 5, 6};
int temp = 0;
int len = arr.length;
//计算数组的长度
for( int i = 0; i < len / 2; i++) {
temp = arr[len - 1 - i];//中间值
arr[len - 1 - i] = arr[i];
arr[i] = temp; //中间值为中介,前后交换
}
for(int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");//6,5,4,3,2,1
}
}
}
1.3 数组作为函数的参数
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
printArray(new int[]{3, 1, 2, 6, 4, 2});
//3 1 2 6 4 2
1.4 数组作为函数的返回值
public static int[] reverse(int[] list) {
int[] result = new int[list.length];
for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
result[j] = list[i];
}
return result;
}
二、二维数组
二维数组可以看成是数组的数组:type[][] typeName = new type[typeLength1][typeLength2];
2.1 二维数组定义
动态初始化:int array2[][] = new int[10][10];
静态初始化:int array4[][] = new int[][] { { 1, 1, 1 }, { 2, 2, 2 } };
2.2 二维数组基本操作
//不定长二维数组
int[][] array = new int[3][];
array[0] = new int[1];
array[1] = new int[2];
array[2] = new int[3];
//获取二维数组的长度
int length1 = array.length;
int length2 = array[0].length;
// 获取二维数组的第一维长度
System.out.println(length1);
// 获取二维数组的第一维的第一个数组长度
System.out.println(length2);
2.3 *杨辉三角*
规律:
- 第一行有 1 个元素, 第 n 行有 n 个元素 ;
- 每一行的第一个元素和最后一个元素都是 1 ;
- 从第三行开始, 对于非第一个元素和最后一个元素的元素的值
arr[i][j]
,arr[i][j] = arr[i-1][j] + arr[i-1][j-1]
。
public class TwoDimentionalArray {
public static void main(String[] args) {
int[][] a = new int[6][];
for (int i = 0; i < a.length; i++) {
// 给每个一维数组开辟堆内存空间,第n行有n个元素
a[i] = new int[i + 1];
// 遍历每一个一维数组,赋值
for (int j = 0; j < a[i].length; j++) {
// 每一行的第一个元素和最后一个元素都是1
if (j == 0 || j == a[i].length - 1) {
a[i][j] = 1;
} else {
// 每一行非第一个元素和最后一个元素的值 = 上一行的同一列 + 上一行的上一列
a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
}
}
}
// 输出杨辉三角
for (int i = 0; i < a.length; i++) {
for (int k = 0; k < a[i].length; k++) {
System.out.print(a[i][k] + "\t");
}
System.out.println();
}
}
}
/*
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
*/
三、Arrays 类
3.1 Arrays.fill()
/*java中的数组初始值都为零,快速填充一个其他值的数组,
使用 Arrays.fill 方法,但只能填充一维数组*/
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int[] arr = new int[5];
int[] b = new int[5];
Arrays.fill(arr, 1);
System.out.println(Arrays.toString(arr)); // [1, 1, 1, 1, 1]
Arrays.fill(b, 2, 4, 2);//用 20 来填充数组b的下标2到4(不包含)
System.out.println(Arrays.toString(b)); // [0,0,2,2,0]
}
}
3.2 Arrays.sort()
int[] a = {2, 7, 34, 12, 44};
int[] b = {3, 32, 88, 56, 23}
//将数组a全部排序
Arrays.sort(a);
//将数组b从下标2到4(不包含)升序排序
Arrays.sort(b, 2, 4);
//2 7 12 34 44
//3 32 56 88 23
3.3 Arrays.binarySearch()
二分法查找,数组必须是有序的或者是用sort()方法排序之后的
//查找成功:如果key在数组中,则返回搜索值的索引
/*1、binarySearch(Object[], Object key);
查找失败:
[1] 搜索值不是数组元素,且在数组范围内,从1开始计数,得“ - 插入点索引值”;
[2] 搜索值是数组元素,从0开始计数,得搜索值的索引值;
[3] 搜索值不是数组元素,且大于数组内元素,索引值为 – (length + 1);
[4] 搜索值不是数组元素,且小于数组内元素,索引值为 – 1。
*/
int a[] = new int[] {1, 3, 4, 6, 8, 9};
int x1 = Arrays.binarySearch(a, 5);
int x2 = Arrays.binarySearch(a, 4);
int x3 = Arrays.binarySearch(a, 0);
int x4 = Arrays.binarySearch(a, 10);
//-4 2 -1 -7
/*2、binarySearch(Object[], int fromIndex, int toIndex, Object key)
查找失败:
[1] 该搜索键在范围内,但不是数组元素,由1开始计数,得“ - 插入点索引值”;
[2] 该搜索键在范围内,且是数组元素,由0开始计数,得搜索值的索引值;
[3] 该搜索键不在范围内,且小于范围(数组)内元素,返回–(fromIndex + 1);
[4] 该搜索键不在范围内,且大于范围(数组)内元素,返回 –(toIndex + 1)
*/
int a[] = new int[] {1, 3, 4, 6, 8, 9};
int x1 = Arrays.binarySearch(a, 1, 4, 5);
int x2 = Arrays.binarySearch(a, 1, 4, 4);
int x3 = Arrays.binarySearch(a, 1, 4, 2);
int x4 = Arrays.binarySearch(a, 1, 4, 10);
// -4 2 -2 -5
参考资料:菜鸟教程 - 学的不仅是技术,更是梦想!
参考文献1:java数组完全解析(干货满满)-CSDN博客
参考文献2:java中数组的binarySearch()方法详解_java binarysearch方法-CSDN博客
参考文献3:JVM内存模型_jvm的内存模型-CSDN博客