网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
**动态初始化**
int[] arr = new int[10];//这里动态初始10个int变量,默认为0
**如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值,比如:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/972a655ae29c452eb35e24df79d0207d.png)
**如果数组中存储元素类型为引用类型,默认值为null**
int[] :int类型数组
double[] :double类型数组
通过类型就可以定义变量,比如:
int[] array,array就是这个类型的变量,这个变量是存储一组相同数据的变量。
**三种数组定义的方式:**
>
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/26fa30ea2d1c490cb735c65837e51c7b.png)
> 第一种:
> int[] array = {1,2,3,4,5,6};定义一个数组且初始化
> 虽然没写new,但实际上也是一个对象
>
>
>
>
> 注意事项:
> int[10] array = {1,2,3,4,5,6};写法错误,int[] 属于类型,中括号里面不能加任何的数字,相当于在这里破坏了它的类型。
>
>
>
>
> 第二种:
> int[] array2 = new int[3];
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/cc28fe35ca9f4de2aac5953bd674ac72.png)
> 定义数组未初始化
>
>
>
>
> 第三种:
> int[] array3 = new int[]{1,2,3,4,5,6};
> ![在这里插入图片描述](https://img-blog.csdnimg.cn/11b653b3303d414f874a697c6a4d0985.png)
> 定义且初始化
> 三种当中用的最多的就是第一种
>
>
>
### 1.3 遍历数组
**所谓 “遍历” 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作,比如:打印。**
可以使用常见的for循环来打印数组,但首要条件是要知道数组的长度
**注意:在数组中可以通过 数组对象.length 来获取数组的长度**
**1.for遍历**
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/b48a1217dc134d7dbdfb3287c33c2d71.png)
**2.for-each**
**for-each 是 for 循环的另外一种使用方式,也叫作增强for循环,能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错,但缺点是拿不到数组的下标**
int[] array = {1, 2, 3};
//遍历array,每拿到一个元素,就存到x中,然后再将x打印出来
for (int x : array) {
System.out.println(x);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/b47b43ade71848c5afcea30671fdb2f4.png)
**3.借助Java的操作数组工具类 Arrays**
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9};
String str = Arrays.toString(array);
System.out.println(str);
System.out.println(Arrays.toString(array));
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/ecdd89bab50c4566b48ade7957f22e59.png)
## 二、数组的存储
### 2.1 JVM内存发布
![在这里插入图片描述](https://img-blog.csdnimg.cn/ed86c8238d4f4b238c7578667d30cf60.png)
**JVM 的内存被划分成了几个区域, 如图所示:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/254c4323c0ea4c3da5b778caba85eef0.png)
内存是一段连续的存储空间,主要用来存储程序运行时数据的。比如:
1. 程序运行时代码需要加载到内存
2. 程序运行产生的中间数据要存放在内存
3. 程序中的常量也要保存
4. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁
* **程序计数器 (PC Register)**: 只是一个很小的空间, **保存下一条执行的指令的地址**
* **虚拟机栈(JVM Stack)**: 重点是**存储局部变量表**(当然也有其他信息). 我们刚才创建的 int [ ] arr 这样的存储地址的引用就是在这里保存.
* **本地方法栈(Native Method Stack)**: 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是**Native**方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
* **堆(Heap)**: JVM所管理的最大内存区域. 使用 **new 创建的对象都是在堆上保存** (例如前面的 new int [ ] {1, 2, 3} ),**堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。**
* **方法区(Method Area)**: 用于**存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据**. 方法编译出的的字节码就是保存在这个区域 。
要理解数组这部分内容我们只简单关心 **堆** 和 **虚拟机栈** 这两块空间即可。
### 2.2 基本类型变量与引用类型变量的区别
* 基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值
* 而**引用数据类型创建的变量,一般称为对象的引用**,其空间中存储的是对象所在空间的地址。
int[] arr = new int[]{1,2,3,4,5};
![在这里插入图片描述](https://img-blog.csdnimg.cn/e58762ad5c5b4500b6ba13dd9336e443.png)
\*\*引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象 。\*\*类似于C语言中的指针,但是Java中引用要比指针的操作更简单 ,结合下面的代码进行理解:
public static void func() {
int a = 10;
int b = 20;
int[] arr = new int[]{1,2,3};
}
在上述代码中,a、b、arr,都是函数内部的变量,因此其空间都在main方法对应的栈帧中分配。
a、b是内置类型的变量,因此其空间中保存的就是给该变量初始化的值。
array是数组类型的引用变量,其内部保存的内容可以简单理解成是数组在堆空间中的首地址,当数组进行创建的时候是在堆空间中创建的对象,而array中存储数组对象的地址。
java中的数组的内存分布要注意和C语言中的区分,不要混淆!
![在这里插入图片描述](https://img-blog.csdnimg.cn/3d7b470a24534bc9b9b783937e0693a4.png)
**引用不指向对象:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/934e4af885da4a2588d45876f25f0fc8.png)
因为array2=null时,array2未指向任何对象,所以不能进行任何的访问.这里出现了空指针异常
**在java中null和0地址没有关系**
**一个引用能不能同时指向多个对象吗?**
![在这里插入图片描述](https://img-blog.csdnimg.cn/b57c319ac5de42e5b3dee6577144c9b7.png)
**对于这个代码来说只能指向一个对象,存一个对象的地址。最终只保存了最后一个对象的地址**
**数组作为方法的参数传递的过程:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/6cded10aec07429bb35bb6b1910d49e3.png)
求解打印结果:
前两种求解:
**func1**
![在这里插入图片描述](https://img-blog.csdnimg.cn/8e26d130fbd648e78f4a510c0ca8a90a.png)
**func2**
![在这里插入图片描述](https://img-blog.csdnimg.cn/f27d6c54222c407faa022578afd033a4.png)
分析例子:下图代表什么
![在这里插入图片描述](https://img-blog.csdnimg.cn/6dec5228081a41d4ab36f6d87f7f9151.png)
代表array2这个引用,指向了array1这个引用指向的对象。
**注意事项:**
引用指向引用这句话 是错误的,引用只能指向对象
引用一定在栈上吗?
不一定,一个变量在不在栈上,是你变量的性质决定的,如果你就是一个局部变量,一定是在栈上的。如果不是,例如,实例成员变量那就不一定就是在栈上的。
## 三、数组在函数中的使用
### 3.1 基本数据类型的传参
public static void swap(int x,int y) {
int h = x;
x = y;
y = h;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
swap(a,b);
System.out.println(“交换后 a=”+a+" b="+b);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/93438d8eac384dd5b3b9f57049dd611f.png)
**基本类型的传参,函数中改变形参,不影响实参.**
### 3.2 引用数据类型的传参
public static void mul(int[] arr) {
for (int i = 0; i < arr.length; i++) {
arr[i]*=2;
}
}
public static void main(String[] args) {
int[] arr = new int[]{1,2,3,4,5};
mul(arr);
for (int x: arr) {
System.out.print(x+" ");
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/a1c9e529687748a28dc173e44fc5ccce.png)
引用类型的传参,函数中改变形参,实参也将被改变.
### 3.3 数组作为函数的返回值
比如:获取斐波那契数列的前N项
public class TestArray {
public static int[] fib(int n){
if(n <= 0){
return null;
}
int[] array = new int[n];
array[0] = array[1] = 1;
for(int i = 2; i < n; ++i){
array[i] = array[i-1] + array[i-2];
}
return array;
}
public static void main(String[] args) {
int[] array = fib(10);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
## 四、数组的练习题
### 4.1 交换两个变量的值
public class TestDemo {
public static void swap(int[] array){
int tmp = array[0];
array[0] = array[1];
array[1] = tmp;
}
public static void main(String[] args) {
int[] array = {10,20};
System.out.println("交换前: "+array[0]+" "+array[1]);
swap(array);
System.out.println("交换后: "+array[0]+" "+array[1]);
}
### 4.2 写一个方法, 将数组中的每个元素都 \* 2
/**
* 在原来的数组上扩大2倍
* @param array
*/
public static void enlarge(int[] array){
for (int i = 0; i <array.length ; i++) {
array[i] = array[i]*2;
}
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
enlarge(array);
System.out.println(Arrays.toString(array));
}
### 4.3 模拟实现tostring函数
public static String myToString(int[] array){
String str = “[”;
for (int i = 0; i <array.length ; i++) {
str = str+array[i];
if(i != array.length-1){
str+= ",";
}
}
str= str + "]";
return str;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7};
String str = myToString(array);
System.out.println(str);
}
### 4.4 找数组中的最大元素
public static int maxNum(int[] array){
if(array == null) return -1;
if (array.length == 0) return -1;
int max = array[0];
for (int i = 1; i <array.length ; i++) {
if(max < array[i]){
max = array[i];
}
}
return max;
}
public static void main(String[] args) {
int[] array = {12,8,14,26,5,7,8};
int max = maxNum(array);
System.out.println(max);
}
### 4.5 查找数组中指定元素(顺序查找)
public static int findNum(int[] array,int key){
for (int i = 0; i <array.length ; i++) {
if(array[i] == key){
return i;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = {2,4,5,6,11,7,8,9};
System.out.println(findNum(array, 7));
}
### 4.6 查找数组中指定元素(二分查找)
//二分查找的必要条件是必须有序的数列
public static int binarySearch(int[] array,int key){
int left = 0;
int right = array.length-1;
while(left <= right){
int mid = (left+right)/2;
if(array[mid] > key){
right = mid - 1;
}else if(array[mid] < key){
left = left + 1;
}else{
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = {12,14,15,16,18,23};
System.out.println(binarySearch(array, 15));
}
### 4.7 检查数组的有序性
public static boolean isUp(int[] array){
for (int i = 0; i <array.length-1 ; i++) {
if(array[i]>array[i+1]){
return false;
}
}
return true;
}
public static void main(String[] args) {
int[] array = {12,13,14,15,16,17,18};
System.out.println(isUp(array));
}
}
### 4.8 数组排序(冒泡排序)
public class TestDemo {
public static void bubbleSort(int[] array){
for (int i = 0; i <array.length-1 ; i++) {
boolean flg = false;
for (int j = 0; j <array.length-1-i ; j++) {
if(array[j]>array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1]= tmp;
flg = true;
}
}
if(flg = false){
return;
}
}
}
public static void main(String[] args) {
int[] array = {12,1,23,15,16,13,17};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
![img](https://img-blog.csdnimg.cn/img_convert/bb20b5d05b5e81e776a45cd12181af9e.png)
![img](https://img-blog.csdnimg.cn/img_convert/317e42584b3dcd002066566a4b049947.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
}
}
}
public static void main(String[] args) {
int[] array = {12,1,23,15,16,13,17};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
[外链图片转存中…(img-wE2tzLTM-1715714651952)]
[外链图片转存中…(img-ZfQfjlzY-1715714651952)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!