Java基础知识梳理(三)数组

1、数组

1.1、概念

数组是同一种类型数据集合;即能够存放多个相同类型的数据的容器。

在Java中数组属于引用类型,即数组是一个对象。这里的数据类型不仅含八大基本数据类型,还包含引用数据类型,如数组里面可以存数组,数组里面可以存放字符串。

1.2、数组定义方式

数组是存放多个数据的容器,Java中需要使用new关键字来创建容器,在创建容器时也要明确容器的大小,即容器中存放数据个数。

有以下格式:

元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

int[] arr = new int[3];//通过new关键字创建了一个长度为3,元素类型是int的数组实体。
元素类型 数组名[] = new 元素类型[]{元素1,元素2,....元素n};
元素类型 数组名[] = {元素1,元素2,....元素n};

1.3、数组内存

​ 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。

​ 堆内存:数组和对象,通过new建立的实例都存放在堆内存中。

​ 方法区:静态成员、构造函数、常量池、线程池

方法体中引用变量和基本变量都在栈上,其他都在堆中。

局部变量的引用型:会把对象存在堆中,而把引用存在栈中。

1.4、数组作用(用途)

在程序中常常需要使用数组,利用循环可以对数组中的数据进行批量操作,大大提高了效率,十分方便。

数组可以存储多个数据,而且可以对数据进行编号,从0开始。操作元素完成可以通过编号(索引)完成。

1.5、数组常见问题

1.5.1、数组角标越界异常

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

在这里插入图片描述

1.5.2、数组空指针异常

public class Demo10 {
    public static void main(String[] args) {
        int arr[] = new int[3];
        //System.out.println(arr[3]);
        arr = null;
        System.out.println(arr[3]);
    }
}

在这里插入图片描述

1.6、数组应用

1.6.1、数组遍历

数组遍历:从角标0开始,主键递增的方位角标对应的每一位元素。

public class Demo{
      public static void main(String[] args) {
        int nums[] = {12,5,87,14,26};// 角标:0 1 2 3 4
        for (int i = 0;i<5;i++){
            System.out.println(nums[i]);
        }
        // Arrays.toString 快速打印数组内容 会打印 []
        System.out.println(Arrays.toString(nums));
    }
}

但是如果数组的内容异常庞大,这时候就需要确定数组的大小

System.out.println("nums数组的大小为:"+nums.length);
nums = new int[]{12,5,87,14,26,77,59,31,7,60,233,1514};
int arr_length = nums.length;
for (int i =0;i<arr_length;i++){
    System.out.println(nums[i]);
}

1.6.2、数组求和

数组求和:

获取多个整数中最大值。

步骤:
  1. 定义变量记录
  2. 通过循环对数组进行遍历。
public class Demo {
    public static int getSum(int []nums){
        int res = 0;// 求和结果
        int length = nums.length;// 获取长度
        for (int i =0;i<length;i++){
            res += nums[i];
        }
        return res;
    }

    // 数据类型... 形式参数 可变长度参数 就是数组
    public static int getSum1(int... nums){
        int res = 0;// 求和结果
        int length = nums.length;// 获取长度
        for (int i =0;i<length;i++){
            res += nums[i];
        }
        return res;
    }

    public static void main(String[] args) {
        int nums[] = {23,17,40,20};
        int sum = getSum(nums);
        System.out.println("数组的求和结果:"+sum);
    }
}

1.6.3、数组求最值

数组求最值:货物多个整数中最大值。
思路:
  1. 数据多了为了便于操作,先存储起来。需要容器,用数组
  2. 多个数据需要进行比较。每次都有较大的数,需要记录下来和下一个数比较。
  3. 将数组中的元素都比一遍。最后,就获取到最大值
步骤:
  1. 接收欲求最大值的数组
  2. 定义一个变量记录住较大的数。
  3. 对数组进行遍历。让元素和较大的值进行比较。如果元素大于较大的数,用变量记录该元素。
  4. 遍历完成后,变量中记录就是最大值
public class Demo02 {
    /**
     * 求数组最大值
     */
    public static int getMax(int nums[]){
        int max = nums[0];// 默认最大值为第一个元素
        for (int i = 1;i<nums.length;i++){// 遍历数组的每一位
            if (max<nums[i]){// 判断当前为是否比max大
                max = nums[i];// 用大值替换max值
            }
        }
        return max;
    }

    public static int getMaxIndex(int nums[]){
        int max = 0;// 默认最大值为第一个元素的角标
        for (int i = 1;i<nums.length;i++){// 遍历数组的每一位
            if (nums[max]<nums[i]){// 判断当前为是否比max大
                max = i;// 用大值的角标替换max值的角标
            }
        }
        return nums[max];
    }
    
    public static void main(String[] args) {
        int nums[] = {7,23,44,16,32,99,34,13};
        Arrays.sort(nums);
        //int max = getMaxIndex(nums);
        //System.out.println("最大值是:"+max);
        System.out.println(Arrays.toString(nums));
        System.out.println(nums[nums.length-1]);
    }
}

1.6.4、数组转字符串

数组转字符串:

将数组中的数字编程字符串输出。如[12,22,13,18,15] 拼接后"1222131815"

思路:

简单的方式就是利用了字符串和任何数据相加都是相连接。+

步骤:

明确1:结果是什么类型?字符串类型。

明确2:参数有什么?一个 int 类型的数组。

1、定义字符串变量存储以后拼接的结果。

2、遍历数组。将每一个数组的元素字符串相连接。

3、判断不是最后一个元素,后面连接逗号,是最后一个元素,后面不连接逗号。

4、将连接后的字符串返回。

/**
 * 数组和字符串
 */
public class Demo03 {
    public static String getStr(int nums[]){
        String str = "[";// 开头
        for (int i =0 ;i<nums.length;i++){// 遍历每一位
            if (i == nums.length-1){
                str += nums[i];// 最后一位
            }else{
                str += nums[i]+", ";// 非最后一位,需要 ,和空格
            }
        }
        str += "]";// 结尾
        return str;
    }

    // 纯数字字符串转化为数组
    public static int[] getArr(String str){
        int str_length = str.length();// 获取字符串长度。
        int arr[] = new int[str_length];// 数组长度和字符长度保持一致
        for(int i = 0;i<str_length;i++){
            char c = str.charAt(i);// 截取每一位
            int num = Integer.parseInt(c+"");// 字符串类型转化为数字类型。
            arr[i] = num;// 每一位赋值
        }
        return arr;
    }

    public static void main(String[] args) {
        //int nums[] = {23,17,3,45,83};
        //String str = getStr(nums);
        //System.out.println(str);
        //System.out.println(Arrays.toString(nums));
        //字符串截取
		//String str1 = "java OOP";
		//System.out.println(str1.charAt(1));
        String str = "65778723617";
        int[] arr = getArr(str);
        System.out.println(getStr(arr));

        str = "65-778-7-23-61-7";
        String[] split = str.split("-");
        System.out.println(Arrays.toString(split));
    }
}

1.6.5、数组反转

数组反转:

将数组中的数据进行反转,如[1,22,17,18,65] 反转后[65,18,17,22,1]

思路:
  1. 需要定义数组反转的功能:

    明确1:函数运算的结果?void 类型或者 int[]

    明确2:参与运行的参数?一个,int[]数组。

  2. 数组反转就是将数组中的值进行位置互换。

    互换的条件是:

    • 0角标和length-1角标位置上的值互换。
    • 1角标和length-2角标位置上的值互换。
    • 以此类推。
  3. 互换到什么时候停止呢?只要头角标大于等于尾角标就停止。

  4. 怎么互换呢?互换就是交换两个空间中的值,可以使用第三方变量。(三元置换)

步骤:
  1. 定义功能,接收数组。
  2. 遍历数组,每遍历一次交换数组两个位置的上的值,start代表头角标,end代表尾角标
  3. 交换每次遍历的两个空间[start,end]中的数据。
class ArrayTest4 
{
	public static void main(String[] args) 
	{
		int[] arr = {1,22,17,18,65};
		printArray(arr); // 输出
		reverseArray(arr); // 反转
		printArray(arr);// 输出
	}
	//1、定义功能,接受数组
	public static void reverseArray(int[] arr)
	{
		//2、遍历数组,每遍历一次交换数组两个位置的上的值,
		//   start代表头角标,end代表尾角标
		for (int start = 0,end=arr.length-1;start<end ;start++,end-- )
		{
			//3、交换每次遍历的两个空间中的数据
			int temp = arr[start];
			arr[start] = arr[end];
			arr[end] = temp;
		}
	}
	//此功能为打印数组
	public static void printArray(int[] arr)
	{
		for (int i=0;i<arr.length ;i++ )
		{
			if(i!=arr.length-1)
				System.out.print(arr[i]+",");
			else
				System.out.println(arr[i]);
		}
	}
}

1.6.6、数组排序

1、选择排序

选择排序是排序中的一种。

算法原则(从小到大排序):

先用数组中第一个空间值和数组中剩余的其他空间值 依次做比较,在比较的过程有任何值比第一个空间值,就用第一个空间值当前这个空间值换位置,直到所有值第一个空间值全部比较完。第一个空间中就放着最小值。接着在使用数组第二个空间值和数组中剩下空间中值做比较,比较方式和前一次相同。以此类推,比较完成。

规律:

第一个空间剩余空间比一圈,第二个空间在和剩余空间比一圈,以此类推,到倒数第二个空间值和最后一个空间值比完,整个数组有有序了。正好符合了外循环循环一次,内循环执行一圈。即外循环控制每次到底使用哪个空间值和剩余空间比较,内循环提供剩余空间。

图解:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ei8qKlLL-1595605146016)(C:\Users\jiauhjh000\Desktop\笔记\第四天\image-20200618102556203.png)]

代码:
/**
* 选择排序。
*/
public static void selectSort(int[] arr)
{
	for(int x=0 ;x<arr.length-1; x++)  //提供比较的空间角标
	{
		for(int y=x+1; y<arr.length; y++) //提供剩余空间的角标
		{
			if(arr[x]>arr[y])  //判断当前外循环角标位置上的值和内循环角标位置上的值
			{
				int temp = arr[x];
				arr[x] = arr[y];
				arr[y] = temp;
			}
		}
	}
}
2、冒泡排序
算法原理:

这种算法和生活中常见的水中气泡的浮沉类似。

规律:
  • 数字第一个空间值和第二个空间值比较,把较大的值存在第二个空间中,接着第二个空间值和第三个空间值作比较,较大的值存在第三个空间中,以此类推直到倒数第二个空间和倒数第一个空间比较,把较大值存放在最后一个空间中。
  • 由于最后一个空间已经是最大值了,那么第二轮算法和第一轮一样,只是最后一次比较是倒数第三个空间和倒数第二个空间比较。把较大的值存在倒数第二个空间中。
  • 以此类推。
图解:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D0r4VVuK-1595605146031)(C:\Users\jiauhjh000\Desktop\笔记\第四天\image-20200618103240320.png)]

代码:
/**
* 冒泡排序。
*/
public static void bubbleSort(int[] arr)
{
	for(int x=0; x<arr.length-1; x++)// 决定了比较范围。
	{
		for(int y=0; y<arr.length-1-x; y++)// 从0开始比较到指定范围,范围逐渐缩小。
		{
			if(arr[y]>arr[y+1])// 两两比较 升序
			{
				int temp = arr[y];
				arr[y] = arr[y+1];
				arr[y+1] = temp;
			}
		}
	}
}

1.6.7、数组查找

1、一般查找

从组中第一个空间开始查找,每取出一个空间值和待查找的数值做比较若相等,就返回当前角标;若数组遍历结束,没有找到相等的值,则返回-1

public static int searchKey(int[] arr,int key)
{
	//遍历查找。
	for(int x=0; x<arr.length; x++)
	{
		if(arr[x]==key) return x;// 找到就返回。
	}
	return -1;//-1,代表的是角标不存在的情况。
}
2、折半查找(二分法)
前提:

必须保证数组已经是有序的。

思路:
  1. 通过角标先获取中间角标上元素。
  2. 让该元素和要找的数据比较。
  3. 如果要找的数大了,缩小范围,要找的范围应该是 中间的角标+1 = = = > ===> ===>尾角标 ; 如果要找的数小了,要找的范围 头角标 = = = > ===> ===>中间角标-1
  4. 不断如此重复,就可以找到元素对应的角标。
public static int binarySearch(int[] arr,int key)
{
	//1,定义三个变量,记录头角标,尾角标,中间角标。
	int max,min,mid;
	min = 0;// 中
	max = arr.length-1;// 大
	mid = (max+min)>>1;// 小  max+min /2
	while(arr[mid]!= key)// 遍历
	{
		if(key>arr[mid])
			min = mid + 1;
		else if(key<arr[mid])
			max = mid - 1;
		//判断元素是否存在。
		if(max<min)
			return -1;
		mid = (max+min)>>1;
	}
	return mid;
}

2、二组数组

2.1、定义

格式:

int[][] arr = new int[3][2];

定义了名称为arr的二维数组, 二维数组中有3个一维数组,每一个一维数组中有2个元素, 一维数组的名称分别为arr[0], arr[1], arr[2]

2.2、图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-emo4U56a-1595605146045)(C:\Users\jiauhjh000\Desktop\笔记\第四天\image-20200618105201765.png)]

2.3、其他定义格式

int[][] arr = new int[3][];// 定义一维数组为null的二维数组。

二维数组中有3个一维数组,每个一维数组都是默认初始化值null。

arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
// 统一赋值

可以对这个三个一维数组分别进行初始化。

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};
  • 第n个一维数组的长度表示方式:arr[n-1].length;

2.4、应用求和

class Array2Demo 
{
	public static void main(String[] args) 
	{
		int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
		int sum = getSum(arr);
		System.out.println("sum="+sum);
	}
	// 求二位数组的和值
	public static int getSum(int[][] arr)
	{
		int sum = 0;
		for (int i=0;i<arr.length ;i++ )// 遍历二维数组每一个一维数组
		{
			for (int j=0;j<arr[i].length ;j++ )// 遍历一维数组的每一个元素
			{
				sum += arr[i][j];
			}
		}
		return sum;
	}
}

3、数组使用心得

数组容器的特点:

1、固定长度 ;

2、元素都有索引;

什么时候使用容器:数据多了,必须先进行存储。然后进行操作。

什么时候使用数组:

数据多,数据个数确定,而且数据与顺序有对应关系。在分析需求时确定:

  1. 需求中的数据是否有对应的有序编号;
  2. 需求中的数据是否需要有序的编号;如果有,就用数组存储。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值