数组

数组

概念:

​ 数组是一个容器,可以同时存放多个数据值

特点:

​ 1.数组是一种引用类型

​ 2.数组当中的多个数据,必须是同种类型

​ 3.数组的长度在程序运行期间不能改变

初始化:

​ 在内存当中创建数组,并且向其中赋予一些默认值

​ 1.动态初始化(指定长度)

​ 格式:数据类型[] 数组名称 = new 数据类型[数组长度];

​ 含义:左侧的数据类型,也就是数组中保存的数据,全都是统一的类型

​ 左侧的中括号代表我是一个数组

​ 左侧的数组名称:给数组起一个名字

​ 右侧的new:代表创建数组的动作

​ 右侧的数据类型:必须和左侧的数据类型保持一致

​ 右侧的数组长度:也就是数组当中,到底能存放多少个数据,是一个int数字

​ 2.静态初始化(指定内容)

​ 格式:数据类型[] 数组名称 = new[]{元素1,元素2,元素3.......}

​ 省略格式:数据类型[] 数组名称 = {元素1,元素2,元素3.......}

​ 根据大括号里面的具体内容推算出长度

注意:

1.初始化可以拆分为两个步骤

2.静态初始化一旦使用省略格式,就不能拆分为两个步骤了。

//静态初始化拆分为两个步骤
int []  arrayA;
arrayA = new int [] {10,2,0}
//动态初始化拆分为两个步骤
int []  arrayB;
arrayB = new int [3] 
//错误写法
//int []  arrayC;
//arrayC = {1,2,3}

获取数组元素

System.out.println(array)

直接打印数组名称得到的是数组的数组对应的内存地址哈希值

访问数组元素的格式:数组名称[索引值]

索引值就是一个int数字,代表数组中元素的编号

数组中元素从0开始,到【数组长度-1】为止

System.out.println(array[0])

使用动态初始化,其中的数组元素自动拥有一个默认值

​ 整数类型,默认值是0;

​ 浮点类型,默认值是0.0;

​ 字符类型,默认值‘\u0000’;

​ 布尔类型,默认值是false;

​ 引用类型,默认值是null。

赋值:array[1] = 123;

静态初始化起始也有默认值,只不过系统自动马上把默认值替换为大括号里的具体数值

数组的内存划分

一个数组的内存划分

image-20210201200114742

两个数组的内存划分

image-20210201200245570

image-20210201200515578

两个常见的异常

数组索引越界异常

如果访问数组元素是,元素索引编号并不存在,那么将会发生数组索引越界异常。ArrayIndexOutOfBoundsException

//索引越界异常ArrayIndexOutOfBoundsException
//int [] array = new int[3];
//System.out.println(array[3])

空指针异常

所有的引用类型,都可以赋值为一个null,但是代表其中什么都没有

数组必须进行new初始化,才能使用其中的元素

如果只是赋值了一个null,没有进行new创建,那么会出现空指针异常NullPointerException

//空指针异常NullPointerException
//int [] array = null;
//System.out.println(array[0])
	array = new int[3];
	System.out.println(array[0])//0

获得数组长度:

数组名称.length

这将会得到一个int数字,代表数组的长度

数组一旦创建,运行期间,数组长度不会发生改变。

image-20210201202013890

arrayC 只是一个名字,后面int[3],int[5]才是一个数组,地址已经改变

数组的遍历输出

遍历数组说的就是对数组当中所有的元素逐一,挨个儿进行处理,默认的处理就是打印输出

public class Demo04Arrary {
    public static void main(String[] args) {
        int[] arrary = {10,20,30,40,50};
        System.out.println(arrary[0]);
        System.out.println(arrary[1]);
        System.out.println(arrary[2]);
        System.out.println(arrary[3]);
        System.out.println(arrary[4]);
        System.out.println("==================");
        //使用数组,次数就是数组的长度
        for(int i = 0; i<5 ; i++){
            System.out.println(arrary[i]);
        }
        System.out.println("==================");
        for(int i = 0; i< arrary.length ; i++){
            System.out.println(arrary[i]);
        }
    }
}

求出数组的最大值

public class ArrayMax {
    public static void main(String[] args) {
        int[] arrary = {10,55,2,1,50,10000};
        int max = arrary[0];
        for(int i = 1;i < arrary.length;i++){
            if(arrary[i]>max){
                max= arrary[i];
            }
        }
        System.out.println(max);
    }

}

数组元素反转

本来的样子[1,2,3,4]

反转的样子[4,3,2,1]

不能使用新的数组,就用原来的唯一的数组

image-20210201203936896

public class ArraryReverse {
    public static void main(String[] args) {
        int[] arrary = {10, 20, 30, 40, 50};
        for (int i = 0; i < arrary.length; i++) {
            System.out.println(arrary[i]);
        }
        System.out.println("=========================");
        for(int min = 0,max = arrary.length-1;min<max;max--,min++){
            int temp = arrary[min];
            arrary[min] = arrary[max];
            arrary[max] = temp;
        }
        for (int i = 0; i < arrary.length; i++) {
            System.out.println(arrary[i]);
        }
    }
}

查找数组中的指定元素(顺序查找)

顺序查找数组中的指定元素
给定一个数组,在给定一个元素,找出该元素在数组中的位置(输出的是该元素在数组中的下标)

public static void main(String[] args) {
        int[] array = {12, 14, 16, 18, 20, 28};
        System.out.println(find(array,16));
    }

    public static int find(int[] arr, int toFind) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == toFind) {
                return i;
            }
        }
        return -1; // 表示没有找到 }
    }

数组的选择排序

img

题目分析:

​ 通过观察发现,本题目要实现把数组元素{13,46,22,65,3}进行排序

  1. 提到数组排序,就要进行元素值大小的比较,通过上图发现,我们想完成排序要经过若干次的比较才能够完成。
  2. 上图中用每圈要比较的第一个元素与该元素后面的数组元素依次比较到数组的最后一个元素,把小的值放在第一个数组元素中,数组循环一圈后,则把最小元素值互换到了第一个元素中。
  3. 数组再循环一圈后,把第二小的元素值互换到了第二个元素中。按照这种方式,数组循环多圈以后,就完成了数组元素的排序。这种排序方式我们称为选择排序。

解题步骤:

  1. 使用for循环(外层循环),指定数组要循环的圈数(通过图解可知,数组循环的圈数为数组长度 - 1)
  2. 在每一圈中,通过for循环(内层循环)完成数组要比较的第一个元素与该元素后面的数组元素依次比较到数组的最后一个元素,把小的值放在第一个数组元素中
  3. 在每一圈中,要参与比较的第一个元素由第几圈循环来决定。如上图所示

a) 进行第一圈元素比较时,要比较的第一个元素为数组第一个元素,即索引为0的元素

b) 进行第二圈元素比较时,要比较的第一个元素为数组第二个元素,即索引为1的元素

c) 依次类推,得出结论:进行第n圈元素比较时,要比较的第一个元素为数组第n个元素,即数组索引为n-1的元素

代码如下:

//选择排序
public static void selectSort(int[] arr) {
    //功能
    //外层循环用来控制数组循环的圈数
    for (int i = 0; i < arr.length-1; i++) {
        //内层循环用来完成元素值比较,把小的元素值互换到要比较的第一个元素中
        for (int j = i+1; j < arr.length; j++) {
            if (arr[i] > arr[j]) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

数组的冒泡排序

冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数 放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较 (因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个 数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。

public class BubbleSort {
    
	public static void bubbleSort(int[] array){
		for(int i=0;i<array.length-1;i++){
			//每经过一次排序就会排出一个数,第i次就排出i个数,所以-i;
			//而最后一次轮回没有可比项,为了防止越界要-1。
			for(int j=0;j<array.length-i-1;j++){
				if(array[j]>array[j+1]){
					int temp=array[j+1];
					    array[j+1]=array[j];
					    array[j]=temp;
				}
			}
		}
	}
	
	//打印原数组
		public static void arry(int[] arry){
			System.out.print("[");
			for(int i=0;i<arry.length;i++){
				if (i!=arry.length-1){
					System.out.print(arry[i]+",");
					}
				else{
					System.out.println(arry[i]+"]");
				}
			}
		}
	public static void main(String[] args){
		int[] array={4,2,5,6,23,43,13};
		arry(array);       //打印原数组
		bubbleSort(array); //调用冒泡排序方法
		arry(array);       //输出排序后数组
	}
}

数组的二分法查找

要使用二分法需要注意: 数组中的元素必须已经按升序排列好

二分法主要思想是将一个数组一分为二,每次查询都能将查询范围在上一次的基础上缩小一半。所以效率非常高。

public class ErFenFa {

    public static void main(String[] args) {
        int[] a = {123,235,45,6,7,9,95,4};
//        由于二分法适合已经排序好的数组所以先将数组进行排序
        for (int i = 0; i < a.length-1; i++) {
            for (int j = 0; j < a.length-1-i; j++) {
                if(a[j+1]<a[j]){
                    int temp = a[j+1];
                    a[j+1] = a[j];
                    a[j] = temp;
                }
            }
        }
        
        System.out.println(Arrays.toString(a));
        System.out.println(Search(a,6));

    }

    private static int  Search(int[] a, int value) {
        int low = 0;
        int high = a.length-1;
        while(low<high){
            int mid=(low+high)/2;
            if(value==a[mid]){
                return mid;
            }
            if(value>a[mid]){
                low=low+1;
            }
            if(value<a[mid]){
                high=mid-1;
                
            }    
        }
        return -1;
    }

}

Arrays的使用

public class ArrarysUse {
    public static void main(String[] args) {
        Integer [] array = {10,2,0,9,18,3,11,66};
        String[] array2 = new String[]{"a","c","2","1","b"};
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
            System.out.println( Arrays.toString(array));//toString(),转换成字符串
            Arrays.sort(array);//从小到大排序
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.equals(array,array2));//比较两个数组是否相等
            System.out.println(Arrays.toString(array2));
            System.out.println(Arrays.binarySearch(array2,"c"));//-6   查找目标元素所在的位置,注意需要先进行排序。
            //需要先进行排序。
            Arrays.sort(array2);
            System.out.println(Arrays.toString(array2));
            System.out.println(Arrays.binarySearch(array2,"c"));//4
            Arrays.fill(array,100);//基于目标元素填充数组
            System.out.println(Arrays.toString(array));
            Arrays.fill(array,1,3,0);
            System.out.println(Arrays.toString(array));
            System.out.println(Arrays.toString(Arrays.copyOf(array2,2)));//复制输出指定长度的数组
    }

}

输出结果

image-20210202133949481

数组作为方法的参数

当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值

public static void printArrary(int [] array){}

数组作为方法的返回值

一个方法可以有0、1、多个返回值,但是只能有0、1个返回值,不能有多个返回值

如果希望一个方法当中产生多个结果数据进行返回,怎么办?

使用一个数组作为返回值即可

任何数据类型都可以作为方法的返回值或者参数

数组作为方法的返回值,返回的是数组的地址值

数组作为方法的参数,传递进去 的是数组的地址值

public class ArrayReturn {
    public static void main(String[] args) {
        int[] result = caculate(1,2,3);
        System.out.println(result[0]);
        System.out.println(result[1]);
        System.out.println(result);
    }
    public static int[] caculate(int a,int b,int c) {
        int sum = a+b+c;
        int avg = sum/3;
        //两个结果都希望返回,需要一个数组  
        /*int[] arrary = new int[2];
        arrary[0] = sum;
        arrary[1] = avg;
        */
        int [] arrary = {sum,avg};
        return arrary;
    }
}

二维数组

  • 数组属于引用数据类型
  • 数组的元素也可以是引用数据类型
  • 一个一维数组A的元素如果还是一个一维数组类型的,则,此数组A称为二维数组
public class ErWei {
    public static void main(String[] args) {
        //一维数组
        int[] arr = new int[]{1,2,3};
        //静态初始化
        int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
        //动态初始化1
        String[][] arr2 = new String[3][2];
        //动态初始化2
        String[][] arr3 = new String[3][];
        //也是正确的写法:
        int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
        int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};//类型推断
        //String[][] arr4 = new String[][4];//错误写法
        //String[4][3] arr5 = new String[][];//错误写法
        //int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};//错误写法
        //调用二维数组
        System.out.println(arr1[0][1]);//2
        System.out.println(arr2[1][1]);//null
        arr3[1] = new String[4];//null
        System.out.println(arr3[1][0]);//null
        System.out.println(arr3[0]);//null
        //二维数组的属性
        System.out.println(arr4.length);//3
        System.out.println(arr4[0].length);//3
        System.out.println(arr4[1].length);//4
        //遍历二维数组
        for(int i = 0;i < arr4.length;i++){
            for(int j = 0;j < arr4[i].length;j++){
                System.out.print(arr4[i][j] + "  ");
            }
            System.out.println();
        }
    }
}

二维数组的默认初始化值

规定:二维数组分为外层数组的元素,内层数组的元素

int[][] arr = new int[4][3];
外层元素:arr[0],arr[1]等
内层元素:arr[0][0],arr[1][2]等

数组元素默认初始化值:

针对于初始化方式一:比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值
内层元素的初始化值为:与一维数组初始化情况相同
针对于初始化方式二:比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错。

内存结构

img

posted @ 2021-02-02 14:07  老虎彡  阅读(21)  评论(0)    收藏  举报