Java数组基础


Java数组的基础

  1. 数组概述

  2. 数组声明创建

  3. 数组使用

  4. 多维数组

  5. Arrays类

  6. 稀疏数组


1. 数组介绍

  • 数组是相同类型数据的有序集合

  • 数组描述相同类型对象的若干个数据,按照一定的先后次序排列组合而成

  • 其中,每一个数据称为一个数组元素,可以通过下标来访问它们

2. 数组声明创建及初始化

  • 第一步声明数组变量,才能在程序中使用数组

    dataType[] arrayName;  
    //如:int[] nums;
  • 第二步使用new操作符来创建数组

    arrayName = new dataType[arraySize];
    //如 nums = new int[10];
  • 第三步给数组中的元素赋值(没有被赋值为默认值,0 或者 null)

    nums[0] = 1;
    num[1] = 2;
    num[2] = 3;
    ...
  • 声明数组和创建数组可以同时完成

    int[] nums = new int[10];
    int[] nums = {1,2,3,4,5}
    //常用这两种写法同时完成
  • 数组三种初始化

    • 静态初始化

      int[] a = {1,2,3,4,5};
      String[] str = {"this", "is", "hello", "world"};
    • 动态初始化

      int[] a = new int[10];
      nums[0] = 1;
      num[1] = 2;
      num[2] = 3;
      ...
    • 默认初始化

      • 数组是引用类型,它的元素相当于类的实例变量,因此数组一旦创建,就会被分配好空间,其中每个元素就会按照实例变量同样的方法被隐式初始化。即没有被初始化的值默认为 0 或者 null,false。

  • 数组的四个基本特点

    • 其长度是确定的。一旦被创建,它的大小不可以改变。

    • 数组里所有元素必须是相同类型

    • 数组元素可以是任何数据类型(基本类型,引用类型)

    • 数组变量属于引用类型,数组本身就是对象,里面每个元素相当于该对象的成员。Java中对象是在堆中的。

3. 数组使用及内存分析

  • 数组使用方法

    • for - each 循环

    • 数组作方法引入参

    • 数组作返回值

      注意定义类型 + 变量名

  • 数组边界

    • 下标合法区间:[0,length-1], 如果越界就会报错。其中 ArrayName.length 就是该数组长度

    • ArrayIndexOutOfBoundsException : 数组下标越界异常!

  • Java内存分析

      • 存放new的对象和数组

      • 可以被所有的线程共享,不会存放别的对象引用

      • 存放基本数据类型(包括具体值)

      • 引用对象的变量(包括存放引用在堆里面的具体地址)

    • 方法区

      • 可以被所以线程共享

      • 包含了所有的class和static变量

4. 多维数组

  • Java使用数组一般不会超过二维数组,二维数组就是特殊的一维数组,每一个元素都是一个一维数组

  • 二维数组创建

    int a[][] = new int[2][4];
  • 多维数组的使用

// 打印二维数组
int[][] array = {{1,2},{2,3},{3,4}};
for(int i=0;i<array.length;i++){
   for(int j=0;j<array[i].length;j++){
       System.out.print(array[i][j]+" ");
  }
}

5. Arrays类

  • 数组工具类 java.util.Arrays

  • 数组对象本身没有声明方法供我们调用,但API中提供了一个工具类Arrays给我们使用,从而完成一些对数组的操作

  • 查看 JDK 帮助文档 或者 Arrays类方法的源代码 ( 学习编程思路)

  • Arrays 中的方法都是 static 修饰的静态方法,在使用的时候可以直接使用类名进行调用。

  • 常用功能

    • 给数组赋值:fill 方法

    • 对数字排序:sort方法(升序)

    • 比较数组:equals方法(比较数组中元素是否相等)

    • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作

6.冒泡排序

  • 冒泡排序式最出名的排序算法,总共有八大排序

  • 冒泡排序很简单,两层循环,外层冒泡轮数,里层一次比较。

  • 我们看到嵌套循环,就应该立马得出这个算法的时间复杂度O(n^2)
    int temp =0;  // 临时变量,用于交换
    // 外层循环,判断我们要走多少次
    for(int i=0;i<array.length;i++){
       // 内层循环,比较相邻的数的大小,并实现交换位置功能
       for(int j=0 ; j< array[i].length-1-i; j++){
           if(array[j+1]<array[j]){
               temp = array[j];
               array[j] = array[j+1];
               array[j+1] = temp;
          }
      }
       System.out.println(Arrays.toString(array));
    }
  • 思考一些,如何优化?

    int temp =0;  // 临时变量,用于交换
    // 外层循环,判断我们要走多少次
    for(int i=0;i<array.length-1;i++){
       // 通过flag标识来减少没有意义的比较
       boolean flag = false;
       // 内层循环,比较相邻的数的大小,并实现交换位置功能
       for(int j=0 ; j< array[i].length-1-i; j++){
           if(array[j+1]<array[j]){
               temp = array[j];
               array[j] = array[j+1];
               array[j+1] = temp;
               flag = true;
          }
           if(flag == false){
               // 如果没有进行数据交换就直接跳出循环
               break;
          }
      }
       System.out.println(Arrays.toString(array));
    }

     

7. 稀疏数组(一种数据结构)

  • 介绍

    • 当一个数组中大部分元素为0,或者同一个值的数组时,就可以使用稀疏数组来保存该数组

    • 稀疏数组的处理方法

      • 记录数组一共几行几列,有多少个不同值

      • 把具有不同值的元素的行和列及值记录在一个小规模的数组中

      • 如同,左边为原始数组,右边为稀疏数组。

      • 第0行记录了原始数组的行列数及有效值个数,其他行数记录了有效值的坐标和值的大小。(n行3列的形式)

  • 示例

    • 需求:编写五子棋游戏中,有存盘退出和续上盘的功能

    • 分析问题:因为该二维数组的很多值默认为0,因此记录了许多没有意义的数据

    • 解决:稀疏数组

      package MethodArray.ArrayStudy;
      public class ArrayTest_5 {
         public static void main(String[] args) {
             // 1. 创建一个二维数组11*11, 0:没有棋子, 1:黑棋, 2:白棋
             int[][] array = new int[11][11];
             array[1][2] = 1;
             array[2][3] = 2;
             // 输出原始的数组
             System.out.println("输出原始的数组");
             for (int[] ints : array) {
                 for (int anInt : ints) {
                     System.out.print(anInt + "\t");
                }
                 System.out.println();
            }
             // 转化为稀疏数组来保存
             int sum=0;     // 获取有效值的个数
             for (int i = 0; i < 11; i++) {
                 for (int j = 0; j < 11; j++) {
                     if(array[i][j]!=0){
                         sum +=1 ;
                    }
                }

            }
             System.out.println("有效值的个数为:" + sum);

             // 1.稀疏数组是一个n行3列的二维数组,第一行三列分别 存储原数组 行列数 及 有效值个数。
             // 2.其他的行数存储 有效值的 行列数 及其 值
             // 3.创建一个稀疏数组
             int[][] smallArray = new int[sum+1][3];
             smallArray[0][0] = 11;
             smallArray[0][1] = 11;
             smallArray[0][2] = sum;
             // 变量二维数组,将 非0 的值存放进去
             int count = 0;
             for (int i = 0; i < array.length; i++) {
                 for (int j = 0; j < array[i].length; j++) {
                     if(array[i][j]!=0){
                         smallArray[count+1][0] = i;
                         smallArray[count+1][1] = j;
                         smallArray[count+1][2] = array[i][j];
                         count+=1;
                    }
                }
            }
             // 打印稀疏数组
             System.out.println("输出稀疏数组");
             for (int[] arr:smallArray){
                 for (int anInt:arr){
                     System.out.print(anInt + "\t");
                }
                 System.out.println();
            }
             System.out.println("==========还原稀疏矩阵=========");
             // 读取稀疏矩阵
             int[][] array1 = new int[smallArray[0][0]][smallArray[0][1]];
             // 还原元素
             for (int n = 1; n < smallArray.length; n++) {
                     array1[smallArray[n][0]][smallArray[n][1]] = smallArray[n][2];
                }
             // 输出原始的数组
             System.out.println("---------------这是稀疏数组还原的数组-----------------");
             System.out.println("输出原始的数组");
             for (int[] ints : array1) {
                 for (int anInt : ints) {
                     System.out.print(anInt + "\t");
                }
                 System.out.println();
            }
            }
        }

       

3. 总结

我基础需要着重加强的地方

  1. 逻辑运算符/位运算符 (a++,2>>3)

  2. 不熟悉几大选择结构

  3. 循环部分(冒泡排序)

  4. 方法部分(Scanner, Arrays, 自定义方法)

  5. 容易忘记定义类型(基本类型, 引用类型)

  6. 没有掌握 自定义变量的妙用 (换位置,求总和,相关注释忘记写)

巩固基础是王道,多复习,多敲代码,慢慢走,不着急。

念念不忘,必有回响!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM