您的位置:首页 > 房产 > 家装 > 【Java宝典】——探索数组的奥秘之旅

【Java宝典】——探索数组的奥秘之旅

2024/12/23 6:49:07 来源:https://blog.csdn.net/Aileenvov/article/details/138443513  浏览:    关键词:【Java宝典】——探索数组的奥秘之旅

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)

🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”

文章目录

  • `Java数组常见报错`
    • `①:ArrayIndexOutOfBoundsException(数组索引超出范围)`
    • `②:NullPointerException(空指针异常)`
  • `数组的三种遍历方式`
    • `Java中栈和堆的关系`
    • `Java中の数据类型`
    • `数组作为返回值进行进行返回`
  • 数组练习
    • 数组转字符串
    • 数组的copy
    • ✨️ `数组的复制`
      • `方法1:使用copyof进行复制`
      • `方法2:使用copyofRange进行部分复制`
      • `方法3:使用arraycopy进行复制`
      • `方法4:使用clone进行复制`
    • `数组的扩容`
    • `顺序查找数组中的指定元素`
      • `法1:循环查找-有序无序都适用`
      • `法2:二分查找-使用前提:元素必须按照从小到大排序`
    • `通过Arrays中的equals关键字判断数组是否相等`
    • `Arrays局部填充用fill关键字`
      • `冒泡排序`
        • `冒泡排序流程图`

Java数组常见报错

①:ArrayIndexOutOfBoundsException(数组索引超出范围)

    public static void main(String[] args) {//java常见报错1:boolean[] array2 = new boolean[10];System.out.println(array2[10]);}

在这里插入图片描述


②:NullPointerException(空指针异常)

    public static void main(String[] args) {//java常见报错2:int[] array = null;System.out.println("数组的长度是: " +array.length);}

在这里插入图片描述


数组的三种遍历方式

    public static void main(String[] args) {int[] array = {1,2,3,4};//Java循环遍历方式1:访问下标形式for (int i = 0 ; i < array.length; i++){System.out.print(array[i]+" ");}System.out.println();//Java循环遍历方式2:for-each 只是遍历程序,不能通过下标访问for (int Aileen : array){System.out.print(Aileen + " ");}System.out.println();//Java遍历循环方式3:toString将数组转换为字符串String ret= Arrays.toString(array);System.out.println(ret);}

public class X {public static void main(String[] args) {int[] array1 = new int[3];array1[0] = 10;array1[1] = 20;array1[2] = 30;System.out.println(array1);int[] array2 = new int[]{1,2,3,4,5};array2[0] = 100;array2[1] = 200;System.out.println(array2);array1 = array2;array1[2] = 300;array1[3] = 400;array2[4] = 500;System.out.println(array1);System.out.println(array2);}
}

在这里插入图片描述

array1这个引用 指向 array2这个引用所指向的对象

在这里插入图片描述
在这里插入图片描述

array1 和 array2这两个引用 指向 的都是array2这个引用所指向的对象
0x87这个对象 当没有引用 再指向这个对象,就被JVM回收了.
int[] array = null;
代表array这个引用 不指向任何对象.
这就意味着0不能调用它的下标,长度等

Java中栈和堆的关系

栈(Stack)是一种后进先出(LIFO)的数据结构,用于存储方法调用和局部变量
每当一个方法被调用时,Java虚拟机会为该方法创建一个栈帧,并将其推入栈中。
栈帧包含了方法的参数、局部变量以及方法返回时需要的信息。
当方法执行完毕后,对应的栈帧会被弹出,释放相应的内存空间。
堆(Heap)是用于动态分配对象的内存区域。
在Java中,所有通过new关键字创建的对象都存储在堆中。
堆是一种可扩展的内存区域,它的大小可以根据需要进行调整。
堆中的对象可以被多个线程共享,因此需要进行线程安全的管理。
栈和堆之间的关系是:栈中存储了对堆中对象的引用。
当我们在栈中声明一个对象引用变量时,实际上只是在栈中创建了一个引用,而对象本身仍然存储在堆中。
通过引用变量,我们可以访问和操作堆中的对象。
____

Java中の数据类型

在Java中,数据类型可以分为基本数据类型和引用数据类型。

基本数据类型是Java语言中预定义的数据类型,它们包括整数类型(byte、short、int、long)、浮点数类型(float、double)、字符类型(char)和布尔类型(boolean)。
基本数据类型的值直接存储在变量中,它们占用固定的内存空间,并且在内存中分配的位置是连续的。
基本数据类型的赋值是将值直接复制给变量。
引用数据类型是由程序员定义的类、接口、数组等类型。
引用数据类型的变量存储的是对象的引用(内存地址),而不是对象本身。
引用数据类型的变量在内存中占用的空间大小是固定的,但它们指向的对象可以动态地分配和释放内存。
引用数据类型的赋值是将对象的引用复制给变量,多个变量可以指向同一个对象。

基本数据类型和引用数据类型的区别总结如下:

  1. 存储方式:基本数据类型的值直接存储在变量中,而引用数据类型的变量存储的是对象的引用。
  2. 内存分配:基本数据类型在内存中分配的位置是连续的,而引用数据类型的对象可以动态地分配和释放内存。
  3. 大小固定性:基本数据类型占用固定的内存空间,而引用数据类型的变量在内存中占用的空间大小是固定的。
  4. 赋值方式:基本数据类型的赋值是将值直接复制给变量,而引用数据类型的赋值是将对象的引用复制给变量。

public class X {public static void main(String[] args) {int[] array = {1,2,3,4};fun1(array);//打印第一个函数的值System.out.println(Arrays.toString(array));System.out.println(array);}public  static void fun1(int[] array22){array22 = new int[]{11,22,33,44,55};}
}

在这里插入图片描述

因为引用只是修改了形参(局部变量)的指向,当程序执行完以后,形参和其对应的堆上的地址就会自动销毁.
程序最后的打印结果是1,2,3,4所以说不是传了引用,就一定能够修改实参的值

在这里插入图片描述
在这里插入图片描述

①形参不能改变实参的值的情况(只修改指向)

因为引用只是修改了形参(局部变量-红色框框内)的指向[这两个引用分别指的是不同的对象.],当程序执行完以后,形参和其对应的堆上的地址(对象)就会自动销毁.
程序最后的打印结果是1,2,3,4所以说不是传了引用,就一定能够修改实参的值
引用变量当中存地址
引用指向对象

在这里插入图片描述
②形参可以改变实参的值的情况(修改同一个指向所指向的对象)

public class X {public static void main(String[] args) {int[] array = {1,2,3,4};fun2(array);for (int i = 0 ; i < array.length; i++){System.out.print(array[i]+" ");}System.out.println();System.out.println(array);}public  static  void fun2(int[] array11){array11[0] = 99;}
}
两个引用(array和array11)同时指向同一个对象,所以通过形参修改,实参也会跟着改变
从上面的例子也可以看出,形参和实参的名字可以一样也可以不一样.

public class X {public static void main(String[] args) {int x = 10;func4(x);System.out.println(x);}public static void func4(int a){a = 20;}}

在这里插入图片描述

从上面的例子可以看出, 传入基本数据类型,不能通过形参修改实参的数值.

数组作为返回值进行进行返回

public class X {public static void main(String[] args) {int[] ret = func5();System.out.println(Arrays.toString(ret));}public static int[] func5(){int[] array = {1,2,3,4};return array;}
}

在这里插入图片描述

在这里插入图片描述

首先创建的ret数组先访问函数func5,
其次为创建的array(引用)这个数组开辟一块空间然后指向堆上的地址0x99.
然后将array的值返回出来赋值给ret,并且指向array的对象,
最后打印并返回出array的值.

数组练习

数组转字符串

public class X {public static void main(String[] args) {int[] arr = {1,2,3,4,5,6};//创建方法的对象String ret = myToString(arr);System.out.println(ret);}//自己创造的转为字符串的方法public static String myToString(int[] arr) {String ret = "[";for (int i = 0; i < arr.length; i++) {ret += arr[i];if(i != arr.length-1 ){ret += ",";}}ret += "]";return ret;}
}
public class X {//但是下面这种写法漏了判断array是否为null的情况.public static void main(String[] args) {int[] array = null;String ret = myToString(array);System.out.println(array);}public static String myToString(int[] array){//判断数组array为null的情况if (array == null){return "null";}String ret = "[";for (int i=0;i < array.length;i++){ret += array[i];if (i != array.length- 1){ret += ",";}}ret += "]";return ret;}
}

数组的copy

public class X {//但是下面这种写法漏了判断array是否为null的情况.public static void main(String[] args) {//先定义一个数组int[] array = {1,2,4,5,8};//开始复制:首先复制他原来的数组空间大小int[] copy = new int [array.length];//通过循环遍历,将原数组的值传入到新创建的数组for (int i = 0; i < copy.length; i++) {copy[i] = array[i];}//打印新创建数组的值System.out.print(Arrays.toString(copy));}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


✨️ 数组的复制

方法1:使用copyof进行复制

import java.util.Arrays;public class x {public static void main(String[] args) {int[] array ={1,2,3,4};//拷贝  array 这个数组 ,长度为 array.lengthint[] copy = Arrays.copyOf(array,array.length);System.out.println(Arrays.toString(copy));}}

在这里插入图片描述

方法2:使用copyofRange进行部分复制

在JAVA中数组的复制from…to范围一般是左闭右开的,如下所示:

import java.util.Arrays;public class x {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = Arrays.copyOfRange(array,1,3);System.out.println(Arrays.toString(copy));}
}

在这里插入图片描述

方法3:使用arraycopy进行复制

所有被native修饰的是由C/C++进行实现的,所有我们不能看到这个方法的源码,但是它的优点是运行速度比较快

import java.util.Arrays;public class x {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] dest = new int[array.length];System.arraycopy(array,0,dest,0,array.length);System.out.println(Arrays.toString(dest));}}

arraycopy方法括号里面参数的含义用通俗的话讲就是从array这个书架的0位置开始拿书把它放到dest这个书架的0位置,这些书的长度是array.length。

方法4:使用clone进行复制

import java.util.Arrays;public class x {public static void main(String[] args) {int[] array = {1,2,3,4,5};int[] copy = array.clone();System.out.println(Arrays.toString(copy));
}
}

数组的扩容

将数组扩大2倍

public class X {public static void main(String[] args) {//数组扩容int[] array = {1,2,3,4};//拷贝array 这个数组 ,新的长度为 array.length * 2array = Arrays.copyOf(array,array.length*2);//array 指向了 新的数组空间System.out.println(Arrays.toString(array));}
}

在这里插入图片描述


顺序查找数组中的指定元素

法1:循环查找-有序无序都适用

public class FindElement {// 主方法,程序的入口点public static void main(String[] args) {// 定义并初始化一个整型数组 arrayint[] array = {1,2,5,4,5};// 定义并初始化另一个整型数组 myarrayint[] myarray = {9,8,7,6,5};// 调用 search 方法搜索数组 array 中的元素 556,并打印返回值System.out.println(search(array, 556));// 调用 search2 方法搜索数组 myarray 中的元素 8,并打印返回值System.out.println(search2(myarray, 8));}// 定义一个静态方法 search,用于在整型数组中搜索给定的 key 值public static int search(int[] array, int key) {// 遍历数组for (int i = 0; i < array.length; i++) {// 如果找到 key 值,返回当前索引if (array[i] == key) {return i;}}// 如果没有找到 key 值,返回 -1return -1;}// 定义另一个静态方法 search2,与 search 方法功能相同,用于在整型数组中搜索给定的 key 值public static int search2(int[] array, int key) {// 遍历数组for (int i = 0; i < array.length; i++) {// 如果找到 key 值,返回当前索引if (array[i] == key) {return i;}}// 如果没有找到 key 值,返回 -1return -1;}
}

法2:二分查找-使用前提:元素必须按照从小到大排序

import java.util.Arrays; // 导入 Arrays 类,用于数组操作public class BinarySearch {public static void main(String[] args) {int[] array = {5, 3, 6, 8, 7}; // 定义并初始化一个整型数组Arrays.sort(array); // 使用 Arrays 类的 sort 方法对数组进行排序System.out.println(Arrays.toString(array)); // 打印排序后的数组,输出格式为 [3, 5, 6, 7, 8]// 调用 binarySearch 方法在数组中搜索键值 111,并打印返回结果System.out.println(binarySearch(array, 111));}// 定义一个静态方法 binarySearch,用于在排序后的数组中进行二分查找public static int binarySearch(int[] array, int key) {int i = 0; // 初始化左边界索引为 0int j = array.length - 1; // 初始化右边界索引为数组长度减 1while (i <= j) { // 当左边界索引小于等于右边界索引时,继续循环int mid = (i + j) / 2; // 计算中间索引if (array[mid] < key) { // 如果中间索引处的值小于键值,说明键值在右半部分i = mid + 1; // 将左边界索引移动到中间索引的下一个位置} else if (array[mid] == key) { // 如果中间索引处的值等于键值,返回中间索引return mid; // 找到键值,返回其索引} else { // 如果中间索引处的值大于键值,说明键值在左半部分j = mid - 1; // 将右边界索引移动到中间索引的前一个位置}}// 如果没有找到键值,返回 -1return -1;}
}

除了通过自己写二分查找以外,Java还可以直接调用Arrays库里面的binarySearch直接进行二分查找。

import java.util.Arrays; // 导入 Arrays 类,用于数组操作public class BinarySearch {public static void main(String[] args) {int[] array = {5, 3, 6, 8, 7}; // 定义并初始化一个整型数组Arrays.sort(array); // 使用 Arrays 类的 sort 方法对数组进行排序System.out.println(Arrays.toString(array)); // 打印排序后的数组,输出格式为 [3, 5, 6, 7, 8]// 调用 binarySearch 方法在数组中搜索键值 111,并打印返回结果System.out.println(Arrays.binarySearch(array, 7));}
}

我们除了通过使用Arrays类里面的sort进行从小到大排序以外,还可以利用reverse进行逆向排序。

import java.util.Arrays; // 导入Arrays类,用于调用数组相关的工具方法,如toString()public class ReverseSorted {public static void main(String[] args) {int[] array = {1,2,3,31,14,5}; // 定义并初始化一个整型数组reverse(array); // 调用reverse方法,传入数组作为参数System.out.println(Arrays.toString(array)); // 打印数组的字符串表示,查看反转后的结果}public static void reverse(int[] array){ // 定义一个名为reverse的方法,用于反转数组int i = 0; // 初始化索引i为0,指向数组的起始位置int j = array.length-1; // 初始化索引j为数组长度减1,指向数组的末尾位置while (i < j){ // 当索引i小于索引j时,继续循环int temp = array[i]; // 将索引i处的元素暂存到临时变量temparray[i] = array[j]; // 将索引j处的元素赋值给索引i处array[j] = temp; // 将临时变量temp的值(原索引i处的元素)赋值给索引j处i++; // 索引i向后移动一位j--; // 索引j向前移动一位}}
}

通过Arrays中的equals关键字判断数组是否相等

import java.util.Arrays;public class Equals {public static void main(String[] args) {int [] array1 = {1,8,4,5};int [] array2 = {1,8,4,5};int [] array3 = {1,2,3,3};System.out.println(Arrays.equals(array1,array2));System.out.println(Arrays.equals(array1,array3));}
}

Arrays局部填充用fill关键字

import java.util.Arrays;public class PartFill
{public static void main(String[] args) {int [] array = new int[10];Arrays.fill(array,1,3,99);//下标1-2处填充为99System.out.println(Arrays.toString(array));}
}

在这里插入图片描述


冒泡排序

冒泡排序流程图

在这里插入图片描述

import java.util.Arrays;public class BubbleSort {public static void main(String[] args) {int[] array = {1,5,3,2,9};System.out.println(Arrays.toString(array));bubbleSort(array);System.out.println(Arrays.toString(array));}public  static void bubbleSort(int[] array){//循环要比较的趟数  ,  5个数据比较4趟for(int i = 0 ; i < array.length-1;i++ ){//---优化:假设本来就有序,进入下面的循环则变为无序。boolean order = false;//假设有序//循环控制每趟比较次数 ,  因为每一次比上一次少比较一趟for (int j = 0; j < array.length - 1 - i;j++){if (array[j] > array[j+1]) {int temp = array[j];array [j] = array[j+1];array[j+1] = temp;order = true;}}//如果为false则有序,直接返回if (order == false) {return;}}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com