数组

一、数组概述

引言

未使用数组前,如下案例如何做?

//案例: 请存储30个同学的成绩
//分析:使用变量来定义
int score1 = 61;
int score2 = 88;
//...
//定义30个变量来存储成绩的数据
//弊端:冗余代码特别多,可读性也很差

//案例升级:30个同学成绩,每个同学都+10分
//弊端:30个同学都要进行+10分的操作,扩展性很差,不方法管理和维护

数组概述

一组连续的内存空间,用于存储相同数据类型的元素

特点:类型相同,长度固定

//案例:给定一个3个长度的整型数组,用于存整数值
//定义一个存3个整数值的空间
int[] a = new int[3];  //数据类型[] 数组名 = new 数据类型[长度];
//通过下标存和取数组的元素值  下标范围:0~长度-1
a[0] = 66;  //赋值
a[1] = 88;
a[2] = 99;
//a[3] = 57;  //ArrayIndexOutOfBoundsException下标越界

/*
		System.out.println(a[0]);  //取值
		System.out.println(a[1]);
		System.out.println(a[2]);
		*/
System.out.println("求数组长度:"+a.length);
//数组遍历:
for(int i=0;i<a.length;i++) {
    System.out.println(a[i]);
}

//案例升级:数组元素都+10
for(int i=0;i<a.length;i++) {
    a[i]+=10;  //每个元素+10---方便管理
    System.out.println(a[i]);
}

二、数组细节

默认值

//数组的默认值:int-0,String-null,double-0.0,char-码值0,boolean-false
int[] a = new int[3];
System.out.println(a[0]);  //int默认值为0(常用)

String[] b = new String[3];
System.out.println(b[0]);  //String默认值为null(常用)

double[] c = new double[3];
System.out.println(c[0]); //double默认值为0.0

创建方式

//数组的创建方式:
//----------动态赋值---------
//1.先声明,再创建空间
int[] a;  //int a[] 不推荐 
a = new int[3];

//2.声明的同时进行创建空间
int[] b = new int[3];  //推荐

//----------静态赋值---------
//3.创建空间的同时进行赋值
int[] c= new int[]{1,3,5}; //后面多少个值,表示长度是多少

//4.简化版
int[] d = {1,3,5};
//场景:优先选择静态赋值,除非用不了静态; 例如循环录入值

三、应用案例

案例1

//1.给定一个整数数组,统计数组中所有元素的平均值。
int[] a = {88,65,79,55};
int sum = 0;  //汇总所有值
for(int i=0;i<a.length;i++) {
    sum += a[i];
}
double avg = (double)sum/a.length;
System.out.println("平均值为:"+avg);

案例2

//2.给定一个整数数组,读入一个整数n,如果n在数组中存在,输出下标,不存在则输出-1。
//分析:先循环遍历数组,判断是否与n相等;如果相等则得到下标,并退出循环
int[] a = {1,3,5,7,9};
System.out.print("读入一个数:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int index = -1;   //记录下标
for(int i=0;i<a.length;i++) {
    if(n==a[i]) {
        index = i;  //记录了下标
        break;
    }
}
System.out.println("下标为:"+index);

斐波拉契数列

//斐波拉契额数列:
//0,1,1,2,3,5,8,13,21,34....
//分析:可以将所有规则的数存储到数组中,数组中本身有标记,只需遍历数组即可完成
System.out.print("请输入斐波拉契额数列的项数(数组长度):");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a=new int[n]; //动态赋值
for(int i=0;i<a.length;i++) { //循环遍历
    if(i==0||i==1) { //下标为0和1时,直接存元素
        a[i] = i;
    }else {
        a[i]=a[i-1]+a[i-2]; //第三个元素=前两个的和
    }
    System.out.print(a[i]+"\t");
}

四、数组扩容

概述:创建一个新数组空间,比原数组空间要大;再将原数组内容一一拷贝到新空间中

自定义扩容

//案例:存储1,3,5元素的数组;拷贝到容量更大的数组中存储
int[] a = {1,3,5};  //原数组
int[] b = new int[a.length+2]; //新空间的数组(扩容数组)
for(int i=0;i<a.length;i++) {
    b[i] = a[i]; //挨个赋值,将原数组内容循环拷贝到目标数组中
}

//打印扩容数组:将数组转字符串返回
System.out.println(Arrays.toString(b));

系统提供扩容

//系统提供的扩容:System.arraycopy;  Arrays.copyof
//System.arraycopy:
//参数1:原数组  参数2:原数组下标位置-0
//参数3:新数组  参数4:目标数组下标位置-0  参数5:原数组长度
int[] a = {1,3,5};
int[] b = new int[a.length+2]; //扩容新数组比原数组大
System.arraycopy(a, 0, b, 0, a.length);  //扩容方法

System.out.println(Arrays.toString(b));  //扩容数组打印

//Arrays.copyOf:
//参数1:原数组   参数2:目标数组长度   返回结果:扩容数组
int[] bb = Arrays.copyOf(a, a.length+2);
System.out.println(Arrays.toString(bb)); //扩容数组打印

五、方法中的数组

数组作为参数

参数是基本类型的应用—-值传递

public static void main(String[] args) {
    //参数为基本类型的应用--值传递
    //案例:传入一个整数值,在方法实现中+1;打印调用处的变量,查看结果
    //结论:值传递,形参的改变不会影响实参
    int a = 3;
    change(a);  //实参
    System.out.println(a);  //3
}

private static void change(int a) { //形参
    a += 1;  //4
}

参数是数组的应用——–地址传递

public static void main(String[] args) {
    //案例2:传入一个数组参数,在形参中元素+1;调用处打印数组;查看结果
    //参数为数组--地址传递
    //结论:地址传递,形参的改变,会影响实参
    int[] a = {1,3,5};
    change(a);
    System.out.println(Arrays.toString(a)); //2,3,5
}

private static void change(int[] a) {
    //a = new int[3]; //如果new了,相当于形参指向了新的地址
    a[0] += 1;
}

可变长参数

public static void main(String[] args) {
    //案例:在main方法中传入数组,并在方法实现中打印该数组元素
    //int[] a = {1,3,5};
    print(new int[]{1,3,6});

    System.out.println("==============");

    print2(1,3,7); //传的参数应该是类型相同
}
//int...a: 可变长参数  本质为数组(查看反编译工具-xjad)
//一旦形参是可变长参数;那么实参会自动将多个参数转成new空间传入
//特点:在一个方法中只能定义一个可变长参数;且必须放在最后
private static void print2(int...a) {
    for(int i=0;i<a.length;i++) {
        System.out.println(a[i]);
    }
}
private static void print(int[] a) {
    for(int i=0;i<a.length;i++) {
        System.out.println(a[i]);
    }
}

数组作为返回值

public static void main(String[] args) {
    //数组作为返回值的案例:模拟Arrays.copyOf
    int[] a = {1,3,5};
    int[] b = copyOf(a,a.length+2);
    System.out.println(Arrays.toString(b));
}

private static int[] copyOf(int[] a, int length) {
    int[] b = new int[length]; //扩容的空间
    for(int i=0;i<a.length;i++) {
        b[i] = a[i];  //挨个赋值给扩容空间
    }
    return b;
}

方法封装

案例:给定一个整数数组,读入一个整数n,如果n在数组中存在,返回下标;否则返回-1(方法封装)

public static void main(String[] args) {
    //案例:给定一个整数数组,读入一个整数n,如果n在数组中存在,返回下标;否则返回-1(方法封装)
    //分析:参数-数组,录入值       返回值:下标
    int[] a = {1,3,5,7};
    Scanner sc = new Scanner(System.in);
    System.out.print("请输入一个整数:");
    int num = sc.nextInt();
    int index = findIndex(a,num);  //查找下标
    System.out.println("找到下标:"+index);
}

private static int findIndex(int[] a, int num) {
    for(int i=0;i<a.length;i++) {
        if(num==a[i]) { //找到下标,则返回
            return i;
        }
    }
    return -1;  //循环完,没找到下标,则返回-1
}

案例:斐波拉契额数列的封装

public static void main(String[] args) {
    //斐波拉契数列的封装
    //0,1,1,2,3,5,8,13,21,34....
    //分析:可以将所有规则的数存储到数组中,数组中本身有标记,只需遍历数组即可完成
    System.out.print("请输入斐波拉契额数列的项数(数组长度):");
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int[] a=new int[n];
    Test2.feiBo(a);  //方法封装--在当前类中调用方法,可省略类名调用
    System.out.println(Arrays.toString(a));  //打印斐波拉契额数列
}

private static void feiBo(int[] a) {
    for(int i=0;i<a.length;i++) {
        if(i==0||i==1) {
            a[i] = i;
        }else {
            a[i]=a[i-1]+a[i-2];
        }
    }
}

六、总结与作业

总结

1.引言
不使用数组前,如果需要存多个数据,会特别麻烦,也不方便管理
数组概述、特点、下标操作、循环遍历(重点)
2.数组细节
默认值、创建方式(动态赋值,静态赋值)
3,应用案例
循环遍历的案例
4.数组扩容(重点)
扩容概述、自定义扩容、系统提供的两种扩容方法
5.方法中的数组
数组作为参数(重点) 可变长参数;数组作为返回值
方法封装(重点)

作业

1、创建整数数组,并进行赋值,长度为5(备注好数组的组成、标识符、长度、下标,数据类型)
2、使用3种方式创建整数数组,长度为5。
3、1个班5人java成绩,创建浮点数数组,使用循环输入、再找到成绩最高的分数,并输出
4、创建数组长度为5,然后长度扩容为10
5、1个班5人java成绩,创建方法,参数为数组,计算平均分(方法1),然后所有学d员50分以下+10分,50分及以上的加5分,并将结果数组返回(方法2),接受后输出

扩展作业:(可选)
自定义MyArrays.toSring(数组参数)的方法实现
int[] a = {1,3,5};
打印结果-->[1,3,5]