Java基础---数据、查找、排序

1 为什么需要数组

1.1 数组介绍

  • 定义:数组是一种基本的数据结构,用于存储固定大小相同类型的元素序列。
  • 特点
    • 类型固定:数组中的所有元素都必须是相同类型的。
    • 连续内存:数组元素在内存中是连续存储的,这使得访问速度快。
    • 索引访问:可以通过索引快速访问任何一个元素。
    • 固定大小:数组的大小在声明时确定,之后不能改变(单维数组)。
  • 用途
    • 存储和管理大量相同类型的数据。
    • 实现算法,如排序、搜索等。
    • 作为函数参数传递数据集合。

1.2 数组快速入门

  • 声明数组

    • int[] myArray; 声明一个整型数组。
    • double[] prices = new double[10]; 声明并初始化一个大小为10的双精度浮点型数组。
  • 初始化数组

    • 静态初始化:在声明时初始化数组。

      int[] myArray = {
             1, 2, 3, 4, 5};
      
    • 动态初始化:先声明数组,然后使用new关键字动态分配大小。

      int[] myArray = new int[5]; // 分配一个大小为5的整型数组
      
  • 访问数组元素

    • 使用索引访问数组元素,索引从0开始。

      int firstElement = myArray[0]; // 获取第一个元素
      
  • 遍历数组

    • 使用for循环遍历数组中的每个元素。

      for (int i = 0; i < myArray.length; i++) {
             
          System.out.println(myArray[i]);
      }
      
  • 数组的长度

    • .length属性可以用来获取数组的长度,即数组中元素的数量。

​ 这个部分提供了数组的基本概念和如何快速开始使用数组。

当然,以下是使用Markdown语法整理的关于Java数组使用的知识点。

2 数组的使用

2.1 动态初始化

动态初始化是指在创建数组时不立即指定数组的元素,而是在创建数组对象后,再为数组分配内存空间。

int[] dynamicArray;
// 声明数组但不立即分配内存

// 稍后分配内存
dynamicArray = new int[10];
// 此时数组的大小为10,但元素默认值为0

在Java中,数组的元素在声明时如果没有显式初始化,则会被自动初始化为默认值。对于整型数组,元素的默认值是0

2.2 静态初始化

静态初始化是在声明数组的同时,直接指定数组的元素。

int[] staticArray = {
   10, 20, 30, 40, 50};
// 声明并初始化数组,数组的大小为5,元素值分别是10, 20, 30, 40, 50

静态初始化允许你定义数组时立即设置数组的元素,这在你需要一个具有特定初始值的数组时非常有用。

2.3 多维数组的初始化

后面会讲到多为数组。

int[][] twoDimensionalArray = {
   
    {
   1, 2, 3},
    {
   4, 5, 6},
    {
   7, 8, 9}
};
// 声明并初始化一个3x3的二维数组

多维数组可以视为数组的数组,通常用于表示矩阵或需要多个维度的数据结构。

3 数组使用注意事项和细节

在使用Java数组时,了解一些注意事项和细节可以帮助你避免常见的错误,并提高代码的效率和可读性。

3.1 避免数组越界

3.1.1错误示例

尝试访问数组的索引超出其长度,将导致ArrayIndexOutOfBoundsException

int[] array = new int[5];
System.out.println(array[5]); // 抛出异常,因为索引5超出了数组的范围

3.1.2错误原因

在Java中,数组索引是从0开始的,所以一个长度为5的数组,其有效索引范围是从0到4。尝试访问索引5的元素会导致ArrayIndexOutOfBoundsException,因为索引5超出了数组的有效范围。

3.1.3异常详情

  • 异常类型ArrayIndexOutOfBoundsException
  • 异常信息:通常包含“Index x out of bounds for length y”的格式,其中x是尝试访问的索引,y是数组的长度。

3.1.4调试和解决

  1. 检查索引值:确保索引值在数组的有效范围内。
  2. 使用循环:使用循环遍历数组时,确保循环条件不会导致越界。
  3. 添加边界检查:在访问数组元素之前,添加检查以确保索引有效。

3.1.5最佳实践:

在访问数组元素之前,始终检查索引是否在有效范围内。

if (index >= 0 && index < array.length) {
   
    System.out.println(array[index]);
}

3.2 理解数组的默认值

  • 细节:当数组被声明并分配内存后,如果没有显式初始化,其元素将被赋予默认值。
  • 示例:对于整型数组,默认值是0;对于浮点型数组,默认值是0.0

3.3 避免使用魔法数字

3.3.1什么是魔法数字

在编程中,“魔法数字”(Magic Number)指的是在代码中直接硬编码的数值,这些数值没有明确的名称或含义,它们被直接嵌入到代码中。魔法数字使得代码难以理解和维护,因为它们的含义不是立即显而易见的。

3.3.2错误示例

在数组操作中直接使用硬编码的数字,这降低了代码的可读性和可维护性。

int[] array = new int[10]; // 魔法数字10

魔法数字的问题

  • 难以理解:新阅读代码的开发者可能不知道数字10的来源和目的。

  • 难以维护:如果需要更改数组的大小,可能需要在代码的多个地方找到并替换这个数字。

  • 代码重复:如果相同的数字在代码中多次出现,每次更改都需要在多个地方进行更新。

  • 缺乏灵活性:硬编码的数字限制了代码的灵活性和可重用性。

3.3.3最佳实践

使用常量变量代替硬编码的数字。

final int ARRAY_SIZE = 10;
int[] array = new int[ARRAY_SIZE];

3.4 注意数组的不可变性

数组在内存中是连续存储的,其大小在声明时就已经确定。因为数组元素的内存地址是连续的,改变数组的大小将需要重新分配内存并复制所有元素到新的位置,这在语言层面上是不提供的。

3.4.1解决和代替方案

  1. 使用动态数组:Java提供了ArrayList这样的动态数组实现,它可以根据需要自动调整大小。

    ArrayList<Integer> list = new ArrayList<>();
    list.add(1); // 添加元素
    
  2. 复制数组:如果需要“扩展”数组,可以创建一个新的数组,并将原始数组的内容复制到新数组中。

    int[] original = new int[]{
         1, 2, 3};
    int[] expanded = new int[]{
         original.length + 1};
    System.arraycopy(original, 0, expanded, 0, original.length);
    
  3. 使用Arrays.copyOf:Java提供了Arrays.copyOf方法来复制数组并扩展大小。

    int[] newArray = Arrays.copyOf(original, original.length + 1);
    
  4. 使用System.arraycopy:可以手动复制数组内容到新的数组中。

    int[] newArray = new int[original.length + 1];
    System.arraycopy(original, 0, newArray, 0, original.length);
    
  5. 使用循环:在某些情况下,可以使用循环来手动复制数组元素。

    复制int[] newArray = new int[original.length + 1];
    for (int i = 0; i < original.length; i++) {
         
        newArray[i] = original[i];
    }
    

3.4.2注意事项

  • 性能考虑:复制数组是一个昂贵的操作,因为它涉及到创建新的内存空间和复制元素。在性能敏感的应用中,应该谨慎使用。
  • 内存管理:在复制数组时,原始数组仍然存在于内存中,直到被垃圾回收器回收。确保不再使用原始数组,以避免内存泄漏。
  • 数据一致性:在复制数组时,要确保所有相关数据保持一致性,特别是在多线程环境中

3.5 复制数组元素时要小心

在Java中,当你将一个数组赋值给另一个数组变量时,它们会指向内存中的同一数组对象。这意味着对一个数组所做的任何更改都会反映在另一个数组上,因为它们是同一个数组的两个引用。

3.5.1浅拷贝示例

int[] array1 = {
   1, 2, 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值