Java基础(六):数组

简介: Java基础(六):数组

一、数组的概述

数组的概念

  • 数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理
  • 数组中的概念
    • 数组名
    • 下标(或索引)
    • 元素
    • 数组的长度

在这里插入图片描述
数组的特点:

  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型
  • 创建数组对象会在内存中开辟一整块连续的空间。占据的空间的大小,取决于数组的长度和数组中元素的类型
  • 数组中的元素在内存中是依次紧密排列的,有序的
  • 数组,一旦初始化完成,其长度就是确定的。数组的长度一旦确定,就不能修改
  • 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快
  • 数组名中引用的是这块连续空间的首地址

数组的分类

1、按照元素类型分:

  • 基本数据类型元素的数组:每个元素位置存储基本数据类型的值
  • 引用数据类型元素的数组:每个元素位置存储对象(本质是存储对象的首地址)

2、按照维度分:

  • 一维数组:存储一组数据
  • 二维数组:存储多组数据,相当于二维表,一行代表一组数据,只是这里的二维表每一行长度不要求一样

在这里插入图片描述

二、一维数组

1、一维数组的声明

格式:

  • 推荐元素的数据类型[] 一维数组的名称
  • 不推荐元素的数据类型 一维数组名[]

举例:

int[] arr;//推荐
int arr1[];//不推荐
double[] arr2;
String[] arr3;

数组的声明,需要明确:

  • 数组的维度:在Java中数组的符号是[],[]表示一维,[][]表示二维
  • 数组的元素类型:可以是任意的Java的数据类型。例如:int、String、Student等
  • 数组名:数组名是个引用数据类型的变量,因为它代表一组数据

2、一维数组的初始化

静态初始化

  • 如果数组变量的初始化和数组元素的赋值操作同时进行,那就称为静态初始化
  • 静态初始化,本质是用静态数据(编译时已知)为数组初始化。此时数组的长度由静态数据的个数决定
  • 一维数组声明和静态初始化格式1:
    ```
    数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,...};

数据类型[] 数组名;
数组名 = new 数据类型[]{元素1,元素2,元素3,...};

- 例如,定义存储1,2,3,4,5整数的数组容器

int[] arr = new int[]{1,2,3,4,5};//正确
//或
int[] arr;
arr = new int[]{1,2,3,4,5};//正确

- <font color="##DC143C">**一维数组声明和静态初始化格式2:**

数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分成两个语句写


>**<font size="3">动态初始化**

- <font color="#dd0000">**数组变量的初始化和数组元素的赋值操作分开进行,即为动态初始化**
- **动态初始化中,只确定了元素的个数(即数组的长度)**
- **而元素值此时只是默认值,还并未真正赋自己期望的值**
- 真正期望的数据需要后续单独一个一个赋值

**格式:**

数组存储的元素的数据类型[] 数组名字 = new 数组存储的元素的数据类型[长度];

数组存储的数据类型[] 数组名字;
数组名字 = new 数组存储的数据类型[长度];


- [长度]:数组的长度,表示数组容器中可以最多存储多少个元素
- **注意:数组有定长特性,长度一旦指定,不可更改。**
- 正确写法

int[] arr = new int[5];

int[] arr;
arr = new int[5];

- 错误写法

int[] arr = new int[5]{1,2,3,4,5};//错误的,后面有{}指定元素列表,就不需要在[]中指定元素个数了


## 3、一维数组的使用

>**<font size="3">数组的长度**

- 数组的元素总个数,即数组的长度
- 每个数组都有一个属性length指明它的长度
- 每个数组都具有长度,而且一旦初始化,其长度就是确定,且是不可变的


>**<font size="3">数组元素的引用**

- 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始
- 这个自动编号称为`数组索引(index)或下标`,可以通过数组的索引/下标访问到数组中的元素
- **数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i]**


>**<font size="3">数组元素的默认值**

- 对于基本数据类型而言,默认初始化值各有不同
- 对于引用数据类型而言,默认初始化值为null(注意与0不同!)

![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d9fa2f284fd05fbac98f07205e33c481.png)


## 4、一维数组内存分析

>**<font size="3">一个一维数组内存图**


```java
public static void main(String[] args) {
      int[] arr = new int[3];
      System.out.println(arr);//[I@5f150435
}

在这里插入图片描述

数组下标为什么是0开始

因为第一个元素距离数组首地址间隔0个单元格

两个一维数组内存图

两个数组独立

public static void main(String[] args) {
   
    int[] arr = new int[3];
    int[] arr2 = new int[2];
    System.out.println(arr);
    System.out.println(arr2);
}

在这里插入图片描述

三、二维数组

1、二维数组的声明与初始化

声明

二维数组声明的语法格式:

  • 推荐:
    • 元素的数据类型[] [] 二维数组的名称;
  • 不推荐(但也支持不报错):
    • 元素的数据类型 二维数组名[][];
    • 元素的数据类型[] 二维数组名[];

例如:

public class Test20TwoDimensionalArrayDefine {
   
    public static void main(String[] args) {
   
        //存储多组成绩
        int[][] grades;

        //存储多组姓名
        String[][] names;
    }
}

静态初始化

格式:

int[][] arr = new int[][]{
  {3,8,2},{2,7},{9,0,1,6}};
  • 定义一个名称为arr的二维数组,二维数组中有三个一维数组
  • 每一个一维数组中具体元素也都已初始化
    • 第一个一维数组 arr[0] = {3,8,2}
    • 第二个一维数组 arr[1] = {2,7}
    • 第三个一维数组 arr[2] = {9,0,1,6}
  • 第三个一维数组的长度表示方式:arr[2].length

举例

int[][] arr = {
  {1,2,3},{4,5,6},{7,8,9,10}};//声明与初始化必须在一句完成

int[][] arr = new int[][]{
  {1,2,3},{4,5,6},{7,8,9,10}};

int[][] arr = new int[3][3]{
  {1,2,3},{4,5,6},{7,8,9,10}};//错误,静态初始化右边new 数据类型[][]中不能写数字

动态初始化

格式1:规则二维表:每一行的列数是相同的

//(1)确定行数和列数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n];
    //其中,m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行
    //其中,n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格

//此时创建完数组,行数、列数确定,而且元素也都有默认值

//(2)再为元素赋新值
二维数组名[行下标][列下标] = 值;

举例:

int[][] arr = new int[3][2];
  • 定义了名称为arr的二维数组
  • 二维数组中有3个一维数组
  • 每一个一维数组中有2个元素
  • 一维数组的名称分别为arr[0], arr[1], arr[2]
  • 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;

格式2:不规则:每一行的列数不一样

//(1)先确定总行数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][];

//此时只是确定了总行数,每一行里面现在是null

//(2)再确定每一行的列数,创建每一行的一维数组
二维数组名[行下标] = new 元素的数据类型[该行的总列数];

//此时已经new完的行的元素就有默认值了,没有new的行还是null

//(3)再为元素赋值
二维数组名[行下标][列下标] = 值;

举例:

int[][] arr = new int[3][];
  • 二维数组中有3个一维数组。
  • 每个一维数组都是默认初始化值null (注意:区别于格式1)
  • 可以对这个三个一维数组分别进行初始化:arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
  • 注:int[][]arr = new int[][3]; //非法

2、数组的长度和角标

  • 二维数组的长度/行数:二维数组名.length
  • 二维数组的某一行:二维数组名[行下标]
    • 此时相当于获取其中一组数据
    • 它本质上是一个一维数组
    • 行下标的范围:[0, 二维数组名.length-1]
    • 此时把二维数组看成一维数组的话,元素是行对象。
  • 某一行的列数:二维数组名[行下标].length,因为二维数组的每一行是一个一维数组。
  • 某一个元素:二维数组名[行下标][列下标],即先确定行/组,再确定列。

举例:

public class Test22TwoDimensionalArrayUse {
   
    public static void main(String[] args){
   
        //存储3个小组的学员的成绩,分开存储,使用二维数组。
        /*
        int[][] scores1;
        int scores2[][];
        int[] scores3[];*/

        int[][] scores = {
   
                {
   85,96,85,75},
                {
   99,96,74,72,75},
                {
   52,42,56,75}
        };

        System.out.println(scores);//[[I@15db9742
        System.out.println("一共有" + scores.length +"组成绩.");

        //[[:代表二维数组,I代表元素类型是int
        System.out.println(scores[0]);//[I@6d06d69c
        //[:代表一维数组,I代表元素类型是int
        System.out.println(scores[1]);//[I@7852e922
        System.out.println(scores[2]);//[I@4e25154f
        //System.out.println(scores[3]);//ArrayIndexOutOfBoundsException: 3

        System.out.println("第1组有" + scores[0].length +"个学员.");
        System.out.println("第2组有" + scores[1].length +"个学员.");
        System.out.println("第3组有" + scores[2].length +"个学员.");

        System.out.println("第1组的每一个学员成绩如下:");
        //第一行的元素
        System.out.println(scores[0][0]);//85
        System.out.println(scores[0][1]);//96
        System.out.println(scores[0][2]);//85
        System.out.println(scores[0][3]);//75
        //System.out.println(scores[0][4]);//java.lang.ArrayIndexOutOfBoundsException: 4
    }
}

3、二维数组的遍历

for(int i=0; i<二维数组名.length; i++){ //二维数组对象.length
    for(int j=0; j<二维数组名[i].length; j++){//二维数组行对象.length
        System.out.print(二维数组名[i][j]);
    }
    System.out.println();
}

举例:

public class Test23TwoDimensionalArrayIterate {
   
    public static void main(String[] args) {
   
        //存储3个小组的学员的成绩,分开存储,使用二维数组。
        int[][] scores = {
   
                {
   85,96,85,75},
                {
   99,96,74,72,75},
                {
   52,42,56,75}
        };

        System.out.println("一共有" + scores.length +"组成绩.");
        for (int i = 0; i < scores.length; i++) {
   
            System.out.print("第" + (i+1) +"组有" + scores[i].length + "个学员,成绩如下:");
            for (int j = 0; j < scores[i].length; j++) {
   
                System.out.print(scores[i][j]+"\t");
            }
            System.out.println();
        }
    }
}

4、二位数组的内存解析

  • 二维数组本质上的元素类型是一维数组的一维数组

举例1:

在这里插入图片描述

举例2:

在这里插入图片描述

四、Arrays工具类的使用


java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法

  • 数组元素拼接
    • static String toString(int[] a) :字符串表示形式由数组的元素列表组成,括在方括号("[]")中。
      • 相邻元素用字符 ", "(逗号加空格)分隔
      • 形式为:[元素1,元素2,元素3。。。]
    • static String toString(Object[] a) :字符串表示形式由数组的元素列表组成,括在方括号("[]")中
  • 数组排序
    • static void sort(int[] a) :将a数组按照从小到大进行排序
    • static void sort(int[] a, int fromIndex, int toIndex) :将a数组的[fromIndex, toIndex)部分按照升序排列
    • static void sort(Object[] a) :根据元素的自然顺序对指定对象数组按升序进行排序
    • static void sort(T[] a, Comparator<? super T> c) :根据指定比较器产生的顺序对指定对象数组进行排序
  • 数组元素的二分查找
    • static int binarySearch(int[] a, int key) 、static int binarySearch(Object[] a, Object key)
      • 要求数组有序,在数组中查找key是否存在,如果存在返回第一次找到的下标,不存在返回负数
  • 数组的复制
    • static int[] copyOf(int[] original, int newLength) :根据original原数组复制一个长度为newLength的新数组,并返回新数组
    • static T[] copyOf(T[] original,int newLength):根据original原数组复制一个长度为newLength的新数组,并返回新数组
    • static int[] copyOfRange(int[] original, int from, int to) :复制original原数组的[from,to)构成新数组,并返回新数组
    • static T[] copyOfRange(T[] original,int from,int to):复制original原数组的[from,to)构成新数组,并返回新数组
  • 比较两个数组是否相等
    • static boolean equals(int[] a, int[] a2) :比较两个数组的长度、元素是否完全相同
    • static boolean equals(Object[] a,Object[] a2):比较两个数组的长度、元素是否完全相同
  • 填充数组
    • static void fill(int[] a, int val) :用val值填充整个a数组
    • static void fill(Object[] a,Object val):用val对象填充整个a数组
    • static void fill(int[] a, int fromIndex, int toIndex, int val):将a数组[fromIndex,toIndex)部分填充为val值
    • static void fill(Object[] a, int fromIndex, int toIndex, Object val) :将a数组[fromIndex,toIndex)部分填充为val对象

举例:

public class ArraysTest {
   
    public static void main(String[] args) {
   
        //1. boolean equals(int[] a,int[] b):比较两个数组的元素是否依次相等
        int[] arr1 = new int[]{
   1,2,3,4,5};
        int[] arr2 = new int[]{
   1,2,3,4,5};

        System.out.println(arr1 == arr2); // false

        boolean isEquals = Arrays.equals(arr1,arr2);
        System.out.println(isEquals); // true


        //2. String toString(int[] a):输出数组元素信息。
        System.out.println(arr1); // [I@4517d9a3

        System.out.println(Arrays.toString(arr1)); // [1, 2, 3, 4, 5]


        //3.void fill(int[] a,int val):将指定值填充到数组之中。
        Arrays.fill(arr1,10);

        System.out.println(Arrays.toString(arr1)); // [10, 10, 10, 10, 10]

        //4. void sort(int[] a):使用快速排序算法实现的排序
        int[] arr3 = new int[]{
   34,54,3,2,65,7,34,5,76,34,67};
        Arrays.sort(arr3);

        System.out.println(Arrays.toString(arr3)); // [2, 3, 5, 7, 34, 34, 34, 54, 65, 67, 76]

        //5. int binarySearch(int[] a,int key):二分查找
        //使用前提:当前数组必须是有序的
        int index = Arrays.binarySearch(arr3,15);
        if(index >= 0){
   
            System.out.println("找到了,索引位置为:" + index);
        }else{
   
            System.out.println("未找到");
        }
    }
}
相关文章
|
27天前
|
存储 Java 索引
Java快速入门之数组、方法
### Java快速入门之数组与方法简介 #### 一、数组 数组是一种容器,用于存储同种数据类型的多个值。定义数组时需指定数据类型,如`int[]`只能存储整数。数组的初始化分为静态和动态两种: - **静态初始化**:直接指定元素,系统自动计算长度,如`int[] arr = {1, 2, 3};` - **动态初始化**:手动指定长度,系统给定默认值,如`int[] arr = new int[3];` 数组访问通过索引完成,索引从0开始,最大索引为`数组.length - 1`。遍历数组常用`for`循环。常见操作包括求和、找最值、统计特定条件元素等。
|
25天前
|
存储 Java C++
Java数组:静态初始化与动态初始化详解
本文介绍了Java中数组的定义、特点及初始化方式。
60 12
|
4月前
|
存储 缓存 算法
Java 数组
【10月更文挑战第19天】Java 数组是一种非常实用的数据结构,它为我们提供了一种简单而有效的方式来存储和管理数据。通过合理地使用数组,我们能够提高程序的运行效率和代码的可读性。更加深入地了解和掌握 Java 数组的特性和应用,为我们的编程之旅增添更多的精彩。
47 4
|
4月前
|
存储 缓存 算法
提高 Java 数组性能的方法
【10月更文挑战第19天】深入探讨了提高 Java 数组性能的多种方法。通过合理运用这些策略,我们可以在处理数组时获得更好的性能表现,提升程序的运行效率。
61 2
|
4月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
124 2
|
4月前
|
存储 Java
什么是带有示例的 Java 中的交错数组?
什么是带有示例的 Java 中的交错数组?
71 9
|
4月前
|
Java
Java数组动态扩容和动态缩减
Java数组动态扩容和动态缩减
43 3
|
4月前
|
存储 算法 Java
Java一分钟之-数组的创建与遍历
数组作为Java中存储和操作一组相同类型数据的基本结构,其创建和遍历是编程基础中的基础。通过不同的创建方式,可以根据实际需求灵活地初始化数组。而选择合适的遍历方法,则可以提高代码的可读性和效率。掌握这些基本技能,对于深入学习Java乃至其他编程语言的数据结构和算法都是至关重要的。
37 6
|
4月前
|
存储 Java 程序员
【一步一步了解Java系列】:何为数组,何为引用类型
【一步一步了解Java系列】:何为数组,何为引用类型
46 1
|
4月前
|
存储 XML Java
如何在 Java 中将常见文档转换为 PNG 图像数组
如何在 Java 中将常见文档转换为 PNG 图像数组
31 1

热门文章

最新文章