欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数组(Array)

程序员文章站 2022-04-24 13:36:29
...

数组

数组的概述&数组的内存分析

之前我们在定义数据的时候,基本上都是用变量来存储数据。但是如果我们的程序中出现大量的数据该怎么办?比如连续输入多个数字,连续输入多个坐标点,对于这种一般而言计算机会创建多个变量来存储这些数据,虽然没有问题,但是显得比较麻烦。我们通过观察可以发现,这些变量基本上类型是共通的,那我们就可以用一个容器将所有的数据进行管理,这类似于字符串,字符串其实就是若干个字符的容器而已,“abc”可以通过索引/角标来获取其中某一个字符,[1,2,3,4,5]类似字符串也能够通过索引/角标来获取其中某一个数字,这个容器我们称之为数组。数组主要解决多变量多数据的存储问题,这方便程序后期统一维护操作数据。

说了这么多关于数组的概述,那么数组的本质到底是什么呢?其实,数组就是一系列空间大小相等且地址连续的一片存储空间。空间大小相等是为了方便统一维护我们的数据,必须得保证数据之间的类型是一样的(多个同类型的变量空间连在一起组成的结构叫数组);至于变量空间地址连续则是为了方便统一操作我们的数据(见下面的数组内存图)。

数组(Array)

  •  数组的定义&数组的常见错误

数组就是一片地址连续且空间大小一致的存储空间(但是每个空间存的还是其他数据的地址),数组存在于堆内存中,但凡在堆中存储的数据都称之为对象,但凡在堆内存中创建的对象都会有默认初始值,整数类型默认0,浮点类型默认0.0,布尔类型默认false,引用数据类型(对象)默认null。

关于数组的一些注意事项:

1.数组变量存的就是数组在堆内存中首元素的地址;

2.数组提供角标来访问数组当中的元素,数组通过角标来访问元素的具体计算方式是:所要访问数据的地址 = 首元素地址+角标*数据类型大小;

3.数组一旦定义下来,其长度不可改变。数组中有几个地址?就看数组有几个元素空间<==>数组的长度。

数组的创建:

1. 数据类型[ ] 数组名 = new 数据类型[长度]   创建数组只指定长度但不指定内容

2. 数据类型[ ] 数组名 = new 数据类型[ ]{1,2,3,4,5}    创建数组指定内容(指定长度)

3. 数据类型[ ] 数组名 = {1,2,3,4,5}   创建数组指定内容(指定长度)

此外 [ ]表示是一维数组,[ ][ ]表示是二维数组。

来看个例子:

class Test04{
    public static void main(String[] args){
        //1.创建长度为5的String型数组
        String[] strArr = new String[5];
	//访问strArr数组中第1个元素
        System.out.println(strArr[0]);
		
	//2.创建长度为5的int型数组
        int[] arr = new int[5];
        //访问arr数组中第4个元素
        System.out.println(arr[3]);
		
        //这个输出语句是访问arr中第11个元素,但因为arr数组的长度只有5,                           
        //所以会出错。错误是"ArrayIndexOutOfBoundsException角标越界"      
	//System.out.println(arr[10]);
		
        //新创建一个变量arr2指向原来的数组,此时数组还是
        //那个数组对象,只不过有两个变量引用到了而已。
        int[] arr2 = arr;
        arr2[0] = 10;
        System.out.println(arr[0]);//10
        arr2 = null;
        //System.out.println(arr2[0]);arr2为空,所以出错NullPointerException空指针异常
		
        arr = null;
        //此时此刻,数组对象没有任何变量引用它
        //数组对象在堆内存中就没有存在的意义了
        //所以该对象变成垃圾,由【垃圾回收器gc】处理
        //【垃圾回收器】是JVM中的一个程序,专门用于负责处理堆内存中垃圾数据的。
        //垃圾的处理并不是及时的,由【gc】来控制,当垃圾堆攒到一定程度时由【gc】来处理
        //特殊的在C/C++中,如果出现对象垃圾,必须程序员手动处理,借助free()及时处理
    }
}

如上述代码所述,数组中常见的错误有两种,一个是"ArrayIndexOutOfBoundsException角标越界",一个是"NullPointerException空指针异常",所以我们写代码的时候要特别注意不要发生这两种错误。另外,当把一个数组变为null后,此时也就没有任何变量去引用它,数组对象在内存中也没有存在意义,所以会被垃圾回收器回收。

  • 基本数组操作

一般有求最大值、最小值,对数组进行遍历,对数组进行赋值等,具体都写在代码中了。

import java.util.*;
class Test05{
    public static void main(String[] args){
        //求最大值、最小值操作
        maxormin();

        //赋值操作
        fuzhi();

        //遍历操作
        bianli();        
    }
    //求最大值、最小值操作
    public static void maxormin(){
        //计算最大值
        //计算最小值的角标
        //获取最大的值10,获取最小值的角标4
        int[] arr={10,2,8,3,1,6,4,7,9,5};
        int max=arr[0];
        int min_index=0;
        for(int i=0;i<arr.length;i++){
            if(arr[i]>max){
                max=arr[i];
            }
            if(arr[i]<arr[min_index]){
                min_index=i;
            }
        }
        System.out.println("最大值"+max);//最大值10
        System.out.println("最小值角标"+min_index);//最小值角标4

    }
    //赋值操作
    public static void fuzhi(){
        Scanner scanner = new Scanner(System.in);
        //System.out.print("请输入10个数字:");
        int[] arr2 = new int[10];
        for(int i=0;i<arr2.length;i++){
            System.out.print("请输入1个数字:");
            arr2[i] = scanner.nextInt();
        }
        for(int i=0;i<arr2.length;i++){
            System.out.print(arr2[i]+" ");
        }
    }
    //遍历操作
    public static void bianli(){
        int[] arr={1,2,3,4,5,6,7,8,9};//[0,8]
        //数组只有一个唯一的属性length,数组的长度
        System.out.println(arr.length);
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
    }
}
  • 查找操作

​​​​​​​查找操作这里就说一下二分查找和线性查找,具体操作都写在代码中了。

class Test06{
    public static void main(String[] args){
        //线性查找
        linearSearch();
		
        //二分查找
        binarySearch();
    }
    public static void binarySearch(){
        //二分查找有个前提,数组必须有序
        /* 
        最好情况 查46    1次就出来了
        最坏情况 查12/60 O(logn)
        */
        int[] arr = {12,17,21,32,38,41,46,49,50,50,51,59,60};
        int key = 46;
        int index = -1;
        int min_index = 0;
        int max_index = arr.length - 1;
        int mid_index = (min_index + max_index) / 2;
        while(arr[mid_index]!=key){
            if(key < arr[mid_index]){
                max_index = mid_index-1;
            }
            if(arr[mid_index] < key){
                min_index = mid_index+1;
            }
            if(min_index > max_index){
                index = -1;
                break;
            }
            mid_index = (min_index + max_index) / 2;
        }
        System.out.println(mid_index);

    }
    public static void linearSearch(){
        /* 
        最好情况 查10 1次就出来了
        最坏情况 查5  10次才出来
        当数组的长度越大的话,最坏情况越差
        时间复杂度(最坏情况)为O(n),是线性阶
        */
        int[] arr={10,2,8,3,1,6,4,7,9,5};
        int key=11;
        int index=-1;//key元素不存在
        for(int i=0;i<arr.length;i++){
            if(arr[i]==key){
                index=i;
                break;
            }
        }
        System.out.println(index);
    }
}

​​​​​​​ 未完待续........

 

相关标签: 知识点总结