Java数组全解:底层特性、创建方式、遍历与二分查找实 一、前言数组是Java最基础、使用频率最高的数据结构之一不管是业务开发还是算法刷题都离不开它。很多初学者只会简单使用数组存取元素但对底层内存结构、默认值规则、增强for循环陷阱、二分查找边界一知半解。二、Java数组核心底层特性1. 内存存储特点1. 内存空间连续数组在堆内存开辟一块连续的内存地址正因如此支持下标随机访问读取指定位置元素时间复杂度O(1)对比链表链表不连续查询需要遍历。2. 长度创建时固定不可扩容数组初始化时必须确定长度一旦分配内存长度永久固定无法直接新增元素。如果需要变长容器要用 ArrayList 底层还是数组扩容是新建数组拷贝。3. 下标从0开始第一个元素下标 0 最后一个下标为 数组长度-1 越界访问会抛出 ArrayIndexOutOfBoundsException 。4. 数组自带默认初始值数组创建分配内存后会自动填充对应类型默认值不需要手动赋值。2. 基本数据类型默认值对照表数据类型 默认值byte/short/int/long 0float/double 0.0char 空字符 \u0000boolean false3. 引用类型数组默认值引用类型包括类、接口、数组、String数组初始化后默认值为 null 。示例Cat catArr new Cat[5]; // 数组中5个元素全是nullString[] strArr new String[3]; // 三个元素都是null4. int与float底层存储补充int 固定32bit1位符号位31位数值位float 固定32bit1位符号位8位阶码23位数值位这也是浮点型计算存在精度丢失的底层原因。5. String底层原理String 底层是 char[] 字符数组Java9之后改为 byte[] 节省内存但数组连续存储、不可变长的特性依旧适用。三、数组3种标准创建方式方式1直接赋值创建静态初始化声明同时直接写入元素编译器自动推算数组长度// 基本类型数组int[] arr {1,2,3};// 引用类型String数组String[] brr {HH,TT,Bob};方式2先分配内存后赋值动态初始化先指定数组长度下标逐个赋值未赋值元素保持默认值int[] arr new int[5];arr[0] 1;arr[1] 3;// arr[2] arr[3] arr[4] 默认值0方式3仅声明数组变量未分配堆内存只定义引用变量没有 new 开辟堆空间此时数组引用为 null 直接使用会空指针 NullPointerExceptionint[] arr;// arr[0] 1; 报错arr为null四、数组两种遍历方式普通for VS 增强for(for-each)1. 普通for循环带下标可修改原数组通过下标直接操作堆内存中的数组元素修改会永久改变原数组内容String[] arr {tom,jck,hello,world};for (int i 0; i arr.length; i) {arr[i] a; // 直接修改原数组对应下标元素}// 输出[a, a, a, a]System.out.println(Arrays.toString(arr));2. 增强for循环 for-each仅遍历无法修改原数组语法 for(元素类型 临时变量 : 数组)核心陷阱循环内的 s 只是数组元素的副本修改副本不会影响堆中原始数组。for (String s : arr) {s aaa; // 仅修改临时副本原数组不变System.out.println(s);}// 输出还是 [a, a, a, a]System.out.println(Arrays.toString(arr));面试必考点for-each适合单纯遍历读取需要增删改数组元素必须用普通for循环。五、数组经典算法二分查找折半查找实战1. 二分查找前提数组必须有序升序/降序核心逻辑不断缩小查找区间每次取中间值对比时间复杂度O(logn)。2. 完整可运行代码package com.qcby.Test;public class test {public static void main(String[] args) {// 升序有序数组int[] arr new int[]{5,7,9,12,15,23,44,65,88};int target 23;System.out.println(binarySearch(arr, target));}public static boolean binarySearch(int[] arr, int target) {int left 0;int right arr.length - 1;// 区间有效条件左边界 右边界while (left right) {// 防止(leftright)数值溢出标准写法int mid left (right - left) / 2;if (arr[mid] target) {// 找到目标值直接返回return true;} else if (arr[mid] target) {// 中间值小于目标目标在右区间左边界右移left mid 1;} else {// 中间值大于目标目标在左区间右边界左移right mid - 1;}}// 循环结束未找到return false;}}3. 关键细节讲解1. mid left (right - left) / 2 优于 (leftright)/2 避免两个大数相加超出int最大值出现数值溢出2. 循环条件 left right 如果写 left right 会漏掉边界元素导致查找失败3. 边界移动 left mid 1 / right mid -1 mid已经对比过不需要再次纳入区间缩小查找范围。4. 运行结果数组中存在23控制台输出 true 修改target为不存在数字则输出 false 。六、面试高频总结1. 数组内存连续随机访问快但无法扩容链表查询慢增删快2. 所有数组创建后一定存在默认值引用类型默认null3. for-each只能读取数组修改临时变量不会改变原数组4. 二分查找只适用于有序数组注意mid防溢出、循环边界 left right 5. 仅声明数组变量不new引用为null调用下标操作报空指针。七、结尾数组是集合、算法的基础很多同学只停留在会用层面面试问到底层存储、for-each原理、二分边界就容易丢分。本文结合手写笔记梳理核心知识点配套可运行实战代码适合Java入门夯实基础、面试突击复习。