2、Java基础---数组

本文详细介绍了Java中的数组,包括创建数组、获取数组长度、读取元素、初始化与赋值、计算最大值、扩展for循环、数组倒序、复制与赋值的陷阱、字符串数组、引用类型和对象的概念,以及final数组的使用。通过实例演示了数组的各种操作,并解释了数组作为对象的特性,以及垃圾回收机制的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组

1、创建数组

通过该声明创建的a是被称为数组变量(array variable)的特殊变量

对数组主体中的各个构成元素的访问(读写)是通过将相当于号码的索引(index)赋入[]中进行的:数组变量名[索引]

索引是表示从首个构成元素开始的第几个构成元素的int型整数值,由于首个构成元素的索引是0,因此各个构成元素从开头开始, 
可以按照a[O] 、a[l] 、a[2] 、a[3] 、a[4] 的顺序进行访问。

对数组进行赋值和显示:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int[] a = new int[5];	// 数组的声明
        a[1] = 37;					// 把37赋给a[1]
        a[2] = 51;					// 把51赋给a[2]
        a[4] = a[1] * 2;			// 把74赋给a[4]

        // 显示全部元素的值
        System.out.println("a[" + 0 + "] = " + a[0]);
        System.out.println("a[" + 1 + "] = " + a[1]);
        System.out.println("a[" + 2 + "] = " + a[2]);
        System.out.println("a[" + 3 + "] = " + a[3]);
        System.out.println("a[" + 4 + "] = " + a[4]);
    }
}

输出:未赋值的a[0]和a[3]的值都是0,数组的构成元素会自动初始化为0

各类型默认值:

2、获取数组中的元素个数

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int[] a = new int[5];	// 数组的声明

        for (int i = 0; i < a.length; i++)
            a[i] = i + 1;

        for (int i = 0; i < a.length; i++)
            System.out.println("a[" + i + "] = " + a[i]);
    }
}

输出:

如上述代码中的 a.length---数组变量名.length:该表达式用来获取数组的元素个数

表示数组元素个数的length不是int型,而是final int型;因此不可以给length赋值,不可以如a.length=10这样随意改变数组的元素个数(编译时会发生错误)

3、读入数组元素的值

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);

        System.out.print("元素个数:");
        //将数值元素个数读入到变量n中
        int n = stdIn.nextInt();			// 读入元素个数
        int[] a = new int[n];				// 创建数组

        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] = ");
            a[i] = stdIn.nextInt();
        }

        for (int i = 0; i < n; i++)
            System.out.println("a[" + i + "] = " + a[i]);
    }
}

输出:

将随机数赋给数组中的全部元素,并显示为横向柱形图

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner stdIn = new Scanner(System.in);

        System.out.print("元素个数:");
        int n = stdIn.nextInt();			// 读入元素个数
        int[] a = new int[n];				// 创建数组
        for (int i = 0; i < n; i++)
            a[i] = 1 + rand.nextInt(10);	// 1~10的随机数
        for (int i = 0; i < n; i++) {
            System.out.print("a[" + i + "] : ");
            for (int j = 0; j < a[i]; j++)
                System.out.print('*');
            System.out.println();
        }
    }
}

输出:

4、数组的初始化和赋值

将数组中的各个元素初始化为1, 2, 3, 4, 5,并进行显示

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};

        for (int i = 0; i < a.length; i++)
            System.out.println("a[" + i + "] = " + a[i]);
    }
}

输出:

数组的初始值就是那些在大括号中的、用逗号分隔并逐一赋给各个元素的值;
创建的数组中的元素个数会根据初始值的个数自动进行设定;
上面程序中(尽管没有显式使用new)会创建一个元素个数为5的数组,从头开始依次将各个元 素初始化为1、2、3、4、5。

读入分数并显示总分和平均分:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int sum = 0;					// 总分
        final int ninzu = 5;			// 人数
        int[] tensu = new int[ninzu];	// 分数

        System.out.println("请输入" + ninzu + "名学生的分数。");
        for (int i = 0; i < ninzu; i++) {
            System.out.print((i + 1) + "号的分数:");
            tensu[i] = stdIn.nextInt();		// 读入tensu[i]
            sum += tensu[i];				// 将tensu[i]加到sum上
        }

        System.out.println("总分为" + sum + "分。");
        System.out.println("平均分为" + (double)sum / ninzu + "分。");
    }
}

输出:

5、计算数组元素中的最大值

如果数组的元素个数为3, 那么三个元素a[O]、a[l]、a(2]中最大值的计算方法如下:

max= a[0]; 
if (a[l] > max) max= a[l]; 
if (a[2] > max) max= a[2]; 

元素个数为n, 计算数组a中最大值的程序如下所示:

max = a[O];
for (int i = l; i< a.length; i++)
if (a[i] > max) max = a[i];

计算元素个数为5的数组中元素最大值的过程::

逐个依次访问数组元素的操作称为遍历,在遍历过程中,当if语句成立(查看的元素值大于当时的最大值max)时,
则将a[i]的值赋给max 当遍历结束时,数组a中的最大元素值就保存到了max中

读入分数并显示最高分:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        final int ninzu = 5;				// 人数
        int[] tensu = new int[ninzu];		// 分数

        System.out.println("请输入" + ninzu + "名学生的分数。");
        for (int i = 0; i < ninzu; i++) {
            System.out.print((i + 1) + "号的分数:");
            tensu[i] = stdIn.nextInt();		// 读入tensu[i]
        }

        int max = tensu[0];
        for (int i = 1; i < tensu.length; i++)
            if (tensu[i] > max) max = tensu[i];

        System.out.println("最高分为" + max + "分。");
    }
}

输出:

线性查找:

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner stdIn = new Scanner(System.in);
        final int n = 12;			// 元素个数
        int[] a = new int[n];		// 声明数组
        for (int j = 0; j < n; j++)
            a[j] = rand.nextInt(10);
        System.out.print("数组a中全部元素的值\n{ ");
        for (int j = 0; j < n; j++)
            System.out.print(a[j] + " ");
        System.out.println(" }");
        System.out.print("要查找的数值:");
        int key = stdIn.nextInt();
        int i;
        for (i = 0; i < n; i++)
            if (a[i] == key)
                break;
        if (i < n)									// 查找成功
            System.out.println("该元素是a[" + i + "]。");
        else										// 查找失败
            System.out.println("该元素不存在。");
    }
}

输出:在线性查找算法中,当存在多个与键值相同的元素时,找到的是它们当中最开头的元素

6、扩展for语句

计算并显示数组中全部元素的总和

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        double[] a = { 1.0, 2.0, 3.0, 4.0, 5.0 };
        for (int i = 0; i < a.length; i++)
            System.out.println("a[" + i + "] = " + a[i]);
        double sum = 0;	// 总和
        for (double i : a)  //:相当于‘...中的’
            sum += i;
        System.out.println("全部元素的总和为" + sum + "。");
    }
}

输出:

上述for循环:遍历数组a从开头到末尾的每一个元素,在循环体中当前正在查看的元素用 i 来表示;

变量 i 并不是表示"索引"的int型整数数值,而是表示double型的"遍历过程中正在查看的元素”。

使用扩展for循环的好处:

•    省去了确认数组长度(元素个数)的操作
•    可以使用与迭代器相同的方法来执行遍历

7、对数组进行倒序排列

交换首个元素a [0]与末尾元素a [6]的值;然后循环执行各自内侧的一个元素值的交换
如果元素个数为n, 则交换次数为n/2 这里的余数会舍弃掉;这是因为当元素个数为奇数时,中间的元素无需进行交换

对数组中的元素进行倒序排列并显示

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner stdIn = new Scanner(System.in);
        System.out.print("元素个数:");
        int n = stdIn.nextInt();  // 读入元素个数
        int[] a = new int[n];	  // 声明数组
        for (int i = 0; i < n; i++) {
            a[i] = 10 + rand.nextInt(90);
            System.out.println("a[" + i + "] = " + a[i]);
        }
        for (int i = 0; i < n / 2; i++) {
            int t = a[i];
            a[i] = a[n - i - 1];
            a[n - i - 1] = t;
        }
        System.out.println("元素的倒序排列执行完毕。");
        for (int i = 0; i < n; i++)
            System.out.println("a[" + i + "] = " + a[i]);
    }
}

输出:

8、数组的复制

 数组的赋值(错误)

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        int[] b = {6, 5, 4, 3, 2, 1, 0};
        System.out.print("a = ");			// 显示数组a中的全部元素
        for (int i = 0; i < a.length; i++)
            System.out.print(a[i] + " ");
        System.out.println();
        System.out.print("b = ");			// 显示数组b中的全部元素
        for (int i = 0; i < b.length; i++)
            System.out.print(b[i] + " ");
        System.out.println();
        b = a;					// 将数组a复制到b(?)
        a[0] = 10;				// 改写数组a[0]的值
        System.out.println("将a赋给了b。 ");
        System.out.print("a = ");			// 显示数组a中的全部元素
        for (int i = 0; i < a.length; i++)
            System.out.print(a[i] + " ");
        System.out.println();
        System.out.print("b = ");			// 显示数组b中的全部元素
        for (int i = 0; i < b.length; i++)
            System.out.print(b[i] + " ");
        System.out.println();
    }
}

输出:

a是元素个数为5的数组{1,2,3,4,5},b是元素个数为7的数组{6, 5, 4, 3, 2, 1, 0};
执行b=a的赋值操作,接下来将10写入到a[0]中。因此,结果应该是数组a变成{10,2,3,4,5},数组b 变成{1,2,3,4,5}

但从运行结果可以看出,a和b都变成了{10,2,3,4,5},
该运行结果表明了如下内容:

赋值后的数组a和b 变成了同一个数组即赋值后的数组变量a 和b 引用了同—个数组主体

使用赋值运符符=进行数组变量的赋值,并不会复制全部元素,赋值运算符的动作如图:

赋值操作b=a是将a的引用目标赋给b 由千是引用目标的复制, 因此赋值的最终结果就变成了数组变量b引用数组a的主体

复制数组时,需要使用循环语句逐一复制全部元素 :

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("元素个数:");
        int n = stdIn.nextInt();		// 读入元素个数
        int[] a = new int[n];
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {	// 数组a中读入数值
            System.out.print("a[" + i + "] = ");
            a[i] = stdIn.nextInt();
        }
        for (int i = 0; i < n; i++)		// 将数组a中的全部元素复制到b中
            b[i] = a[i];
        System.out.println("已经将a中的全部元素复制到了b中。 ");
        for (int i = 0; i < n; i++)		// 显示数组b
            System.out.println("b[" + i + "] = " + b[i]);
    }
}

输出:

8、字符串数组

字符串可以用String型来表示,因此字符串数组的类型就是String[]型。

import java.util.Random;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Random rand = new Random();
        Scanner stdIn = new Scanner(System.in);
        String[] monthString = {
                "January", "February", "March", "April", "May", "June", "July",
                "August", "September", "October", "November", "December"
        };
        int month = rand.nextInt(12);	// 目标月份:0~11的随机数
        System.out.println("题目是" + monthString[month]);
        while (true) {
            System.out.print("是几月呢:");
            int m = stdIn.nextInt();
            if (m == month + 1) break;
            System.out.println("回答错误。");
        }
        System.out.println("回答正确。");
    }
}

输出:

9、引用类型和对象

显示数组变量的值

public class Main {
    public static void main(String[] args) {
        int[] a = new int[5];
        System.out.println("a = " + a);
        a = null;
        System.out.println("a = " + a);
    }
}

输出:程序显示的并不是数组元素的值. 而是数组变量本身的值

 int[] a = new int[5]:数组的声明--使用new创建的数组主体与一般的变量不同,它是在程序运行时创建的,因此会被动态分配存储空间,数组主体与一般变量的性质不同,被称为对象(object)用于指向对象的变量的类型就是引用类型(reference type)。数组变量的类型是数组类型(array type), 这是引用类型的一种

a = null,null赋给数组变址a,null是被称为空常量(null literal)的一种常址 。
被赋入空常址的a就是空引用(null reference)。 空引用是表示什么都不引用的一种特殊引用.其类型就是空类型(null type)。

垃圾回收
对于数组变量,当赋入null, 或者赋入其他数组主体的引用时,数组主体将不再被任何变量引用,变为垃圾。
垃圾残留会导致存储空间不足, 因此,不再被任何变量引用的对象所占用的空间会被自动释放,以便能够再次使用。
像这样,释放不再需要的对象空间,以便能够再次使用的处理称为垃圾回收(garbage collection)。

10、final 数组

数组变量还可以像下面这样声明为final变量:

final int[] a = new int[5]; 

变成final (值不可以被改写)的是数组a的引用目标, 而各个元素的值可以被改写

a[0] = 10; 	//正确
a= null; 	//错误
a = new int[l0]; 	//错误

如果将数组变量声明为final,就可以防止误赋入null, 或者赋入其他数组主体的引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值