当前位置: 首页 > news >正文

【Java SE】认识数组

文章目录

  • 一、为什么需要数组?
  • 二、数组的基本概念
    • 什么是数组?
    • 数组的创建与初始化
      • 1. 数组的创建
      • 2. 数组的初始化
      • 初始化注意事项:
  • 三、数组的使用方法
    • 1. 访问数组元素
    • 2. 遍历数组
  • 四、数组是引用类型
    • JVM内存简化模型
    • 基本类型与引用类型的区别
    • 引用变量的特性
    • 认识null
  • 五、数组的应用场景
    • 1. 作为函数参数
    • 2. 作为函数返回值
  • 六、数组常用操作实战
    • 1. 数组转字符串
    • 2. 数组拷贝
    • 3. 数组查找
    • 4. 数组排序
    • 5. 数组逆序
  • 七、二维数组
  • 总结

数组是Java中最基础也最常用的数据结构之一,它为我们提供了一种高效存储和操作相同类型数据的方式。本文将从数组的基本概念出发,详细讲解数组的创建、初始化、使用方法以及相关实战技巧,帮助你全面掌握Java数组的核心知识。

一、为什么需要数组?

想象一个场景:如果我们需要存储5个学生的成绩,使用基本变量可以这样写:

int score1 = 70;
int score2 = 80;
int score3 = 85;
int score4 = 60;
int score5 = 90;

但如果有20个、100个甚至更多学生呢?显然,创建大量单独的变量既繁琐又难以维护。这时候,数组的价值就体现出来了——它可以存储多个相同类型的元素,并且这些元素在内存中占据连续的空间。

二、数组的基本概念

什么是数组?

数组是相同类型元素的集合,在内存中占据连续的存储空间。可以把数组想象成一排连续的"车位":

  • 每个"车位"存储一个元素,且所有元素类型相同
  • 每个"车位"有唯一编号(下标),从0开始递增
  • 可以通过编号快速访问对应的元素

数组的创建与初始化

1. 数组的创建

Java中创建数组的基本语法:T[] 数组名 = new T[N];

int[] array1 = new int[10]; // 能容纳10个int类型元素的数组
double[] array2 = new double[5]; // 能容纳5个double类型元素的数组
String[] array3 = new String[3]; // 能容纳3个字符串元素的数组

其中,T是元素类型,N是数组长度。

2. 数组的初始化

数组初始化分为两种方式:动态初始化和静态初始化。

动态初始化:创建数组时指定长度,元素使用默认值

int[] array = new int[10]; // 所有元素初始化为0

静态初始化:创建数组时直接指定元素值

// 完整格式
int[] array1 = new int[]{0,1,2,3,4,5};
// 简化格式(推荐)
int[] array2 = {0,1,2,3,4,5};

初始化注意事项:

  • 静态初始化时,编译器会自动计算数组长度
  • 静态初始化的简化格式不能拆分声明和赋值
  • 基本类型数组的默认值:数值类型为0,char\u0000,布尔类型为false
  • 引用类型数组的默认值为null

三、数组的使用方法

1. 访问数组元素

数组通过下标访问元素,语法为数组名[下标]

int[] array = {10, 20, 30, 40, 50};
System.out.println(array[0]); // 访问第一个元素,输出10
array[0] = 100; // 修改第一个元素的值

注意:数组下标从0开始,范围是[0, 数组长度-1],超出范围会抛出ArrayIndexOutOfBoundsException异常。

2. 遍历数组

遍历数组就是访问数组中的每个元素,常用两种方式:

普通for循环

int[] array = {10, 20, 30, 40, 50};
for(int i = 0; i < array.length; i++){ // array.length获取数组长度System.out.println(array[i]);
}

增强for循环(for-each)

int[] array = {1, 2, 3};
for (int x : array) { // 直接获取元素值,无需下标System.out.println(x);
}

四、数组是引用类型

理解数组的引用特性是掌握Java数组的关键,这需要先了解JVM的内存分布:
在这里插入图片描述

JVM内存简化模型

  • 虚拟机栈:存储局部变量和方法调用信息
  • :存储通过new创建的对象和数组
  • 方法区:存储类信息、常量等

基本类型与引用类型的区别

  • 基本类型变量:直接存储值,位于栈中
  • 引用类型变量:存储对象在堆中的地址,位于栈中,通过地址操作对象
public static void func() {int a = 10; // 基本类型,栈中直接存储值int[] arr = new int[]{1,2,3,4,5}; // 引用类型,栈中存储地址,数组元素在堆中
}

在这里插入图片描述

引用变量的特性

多个引用可以指向同一个数组对象:

int[] array1 = new int[3];
array1[0] = 10;
int[] array2 = array1; // array2和array1指向同一个数组
array2[0] = 20; // 修改array2指向的数组,array1也会受影响
System.out.println(array1[0]); // 输出20

认识null

null表示"空引用",即不指向任何对象:

int[] arr = null;
System.out.println(arr[0]); // 抛出NullPointerException

五、数组的应用场景

1. 作为函数参数

数组作为参数传递时,传递的是引用(地址),函数内部修改会影响原数组:

public static void main(String[] args) {int[] arr = {1, 2, 3};func(arr);System.out.println("arr[0] = " + arr[0]); // 输出10
}public static void func(int[] a) {a[0] = 10; // 修改数组内容
}

2. 作为函数返回值

数组可以作为返回值,方便返回多个结果:

// 获取斐波那契数列的前n项
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;
}

六、数组常用操作实战

1. 数组转字符串

使用Arrays.toString()方法可以方便地将数组转为字符串:

import java.util.Arrays;int[] arr = {1,2,3,4,5};
System.out.println(Arrays.toString(arr)); // 输出[1, 2, 3, 4, 5]

2. 数组拷贝

使用Arrays.copyOf()Arrays.copyOfRange()进行数组拷贝:

int[] arr = {1,2,3,4,5};
// 拷贝整个数组
int[] newArr = Arrays.copyOf(arr, arr.length);
// 拷贝指定范围(从下标2到4,不包含4)
int[] rangeArr = Arrays.copyOfRange(arr, 2, 4); // 结果为[3,4]

3. 数组查找

顺序查找:遍历数组寻找目标元素

public static int find(int[] arr, int target) {for (int i = 0; i < arr.length; i++) {if (arr[i] == target) {return i; // 找到返回下标}}return -1; // 没找到返回-1
}

二分查找:针对有序数组的高效查找(时间复杂度O(log n))

public static int binarySearch(int[] arr, int target) {int left = 0;int right = arr.length - 1;while (left <= right) {int mid = (left + right) / 2;if (target < arr[mid]) {right = mid - 1; // 去左侧查找} else if (target > arr[mid]) {left = mid + 1; // 去右侧查找} else {return mid; // 找到返回下标}}return -1; // 没找到
}

4. 数组排序

冒泡排序:通过相邻元素比较交换实现排序

public static void bubbleSort(int[] arr) {for (int i = 0; i < arr.length; i++) {for (int j = 1; j < arr.length - i; j++) {if (arr[j-1] > arr[j]) {// 交换元素int tmp = arr[j-1];arr[j-1] = arr[j];arr[j] = tmp;}}}
}

实际开发中推荐使用Java内置的排序方法:

Arrays.sort(arr); // 效率更高的排序实现

5. 数组逆序

通过首尾交换实现数组逆序:

public static void reverse(int[] arr) {int left = 0;int right = arr.length - 1;while (left < right) {// 交换左右元素int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}
}

七、二维数组

二维数组可以理解为"数组的数组",即每个元素都是一个一维数组:

// 定义二维数组
int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};// 遍历二维数组
for (int row = 0; row < arr.length; row++) {for (int col = 0; col < arr[row].length; col++) {System.out.print(arr[row][col] + "\t");}System.out.println();
}

注意:

  • 二维数组要用{}手动区分行和列
  • 定义时行不能省略,列可以省略
  • 可以定义不规则数组:
int[][] arr = new int[3][];
arr[1] = new int[3];
arr[2] = new int[5];

总结

数组作为Java中最基础的数据结构,掌握它的使用是进行Java编程的必备技能。本文介绍了数组的概念、创建、初始化、使用方法及常见操作,这些知识将为你后续学习更复杂的数据结构打下坚实基础。

数组的核心特点是连续存储空间和固定长度,这使得它具有快速访问的优势,但也带来了长度不可变的限制。在实际开发中,要根据具体需求选择合适的数据结构,当需要动态调整大小的集合时,可以考虑Java集合框架中的ArrayList等类。

http://www.dtcms.com/a/342723.html

相关文章:

  • 【Protues仿真】基于AT89C52单片机的舵机和直流电机控制
  • 【新启航】3D 扫描逆向抄数全流程工具与技能:从手持设备到 CAD 建模的 10 项核心配置解析
  • windows10安装playwright
  • Workerman在线客服系统源码独立部署
  • 笔记本电脑Windows+Ubuntu 双系统,Ubuntu无法挂载Windows的硬盘 报错问题解决
  • TDengine IDMP 运维指南(常见问题)
  • 天眼应急案例(二)
  • 一句话生成uml图相关操作
  • MTK平台蓝牙学习-- 如何查看蓝牙连接参数
  • Vitest 测试框架完全指南 – 极速单元测试解决方案
  • selenium3.141.0执行JS无法传递element解决方法
  • 【自记】Power BI 中 VALUES 和 DISTINCT 在可接收的参数类型上的区别。
  • 【每天一个知识点】 时空组学(Spatiotemporal Omics)
  • Nginx学习记录
  • 移动端网页调试实战 IndexedDB 与本地存储问题的排查与优化
  • 阿里云 AI 搜索 DeepSearch 技术实践
  • 网络流量分析——基础知识(二)(Tcpdump 基础知识)
  • 21.web api 12
  • Mybatis执行SQL流程(六)之Executor执行器
  • ubuntu配置Zotero+翻译插件+坚果云同步
  • 30、ICS/OT 攻击溯源 (电力系统) 模拟组件 - /安全与维护组件/ics-attack-forensics
  • 学习 k 均值聚类算法的心得
  • 记录一次el-table+sortablejs的拖拽bug
  • UTF-8 编码
  • 基于IPO智能粒子优化的IIR滤波器参数识别算法matlab仿真
  • 250821-RHEL9.4上Docker及Docker-Compose的离线安装
  • 大数据仓库分层
  • windows 下控制台只能输入或输入输出的问题
  • Java -- 互斥锁--死锁--释放锁
  • 机器学习两大核心算法:集成学习与 K-Means 聚类详解