Java-数组(基础篇)

Java-数组(基础篇)

Java中的数组是一个复合数据类型
数组中的元素具有相同的类型,元素类型可以是基本数据类型类的对象,也可以是数组类型数组元素在内存中是按着顺序排列的,通过一个整型下标可以访问数组中的每一个值。例如,如果a是一个整型数组,a[i]就是数组中下标为i个整数。
简单来说,数组就是同种类型数据的有序集合
数组必须经过声明、构造、赋初值三个步骤以后才能有效使用。

数组的声明

声明一个一维数组的格式有两种:

元素数据类型[] 数组名称;
元素数据类型 数组名称[];

注释:对于上面使用声明数组的两种形式,大多数程序员喜欢使用第一种风格,因为它将类型int[](整型数组)与变量名分开了。

即在声明数组变量时,需要指出数组类型(数组元素类型紧跟[])和数组变量的名字。下面声明了整型数组a
int[] a;
不过,这条语句只声明了变量a并没有将a初始化为一个真正的数组(如图1)。应该使用new运算符创建数组。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传数组声明

声明一维数组的注意事项:

  1. 数组的类型可以是复杂结构类型,如类类型
  2. 声明数组要使用中括号[],不要错用小括号或大括号。
  3. []里面声明都不能有,Java在声明数组时不允许在方括号内指定数组元素的个数。

###数组的创建
数组的声明仅确定了数组的名字和元素类型,仅此而已。所以还不能使用它,必须进一步把数组创建处理,让它具备自己的内存空间
Java使用new运算符来创建数组。
一维数组创建的格式如下:
数组名称 = new 元素数据类型[元素个数];
例如前面声明的整型数组a,则应该这样创建:
a = new int[10];//创建包含10个元素的整型数组a
这条语句创建了一个可以存储 10 10 10个整数的数组,数组长度不要求必须是常量new int[n]会创建一个长度为n的数组。
这个数组的下标从 0 ~ 9 0~9 09(不是 1 ~ 10 1~10 110)。一旦创建了数组,就可以给 数 组 元 素 赋 值 数组元素赋值

注释:计算机将会按照创建数组时中括号内整数值来为它分配内存空间,这个整数值也就是数组元素的个数,又称为数组的长度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传int[] a

警告:如果创建了一个 10 10 10个元素的数组,并且试图访问元素== a [ 10 ] a[10] a[10]==(或任何在 0 ~ 9 0~9 09之外的下标),程序就会引发“array index out of bounds”异常而终止执行。要想获得数组中的元素个数,可以使用array.length(array此处放的是数组名)。例如:a.length(下面详细介绍);

import java.util.Arrays;
public class DemoJava 
{
	public static void main(String[] args) 
	{
		int[] a;
		a = new int[10];
		a[10] = 10;		
	}
}

程序运行结果:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
	at DemoJava.main(DemoJava.java:8)

一旦创建了数组,就不能再改变它的大小/长度(尽管可以改变每一个数组元素的值)。如果经常需要在运行过程中扩展数组的大小。即应该使用另一种**数据结构——数组列表(array list)**有关数组列表的详细内容以后会扩展,并且在此处放上链接(插个眼)。
创建一维数组的注意事项:

  1. 一维数组在声明时,[]里必须为空,但在使用new运算符进行创建的时候,[]里必须指明数组的长度,只有这样系统才知道该给这个数组分配多少内存
  2. Java允许在创建数组时使用整型变量来指定数组元素的个数,这为数组的使用带来了很大的灵活性。例如:
int size = 20;
double[] doubleArray = new double[size];

数组的初始化

new运算符创建一个数组时,系统就自动将这个数组初始化好了,也就是说,这个数组的各个元素都被赋了初始值。各类型默认初始化值如表所示:

数组元素的类型初始值数组元素的类型初始值
对象引用null布尔变量false
整型变量0字符变量'\u0000'
浮点变量0.0

注释:创建一个数字数组时,所有元素都初始化为0boolean数组的元素会初始化为false对象数组的元素则初始化为一个特殊值null这表示这些元素(还)未存放任何对象

Java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式。下面是一个例子:
int[] smallprimes = {2,3,5,7,11,13};
请注意,在使用这种语句时,不需要调用new
甚至还可以初始化一个匿名的数组
new int[]{17,19,23,29,31,37};
这种表示法将创建一个新数组并且利用括号中提供的值进行初始化数组的大小就是初始值的个数。使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组。例如:

smallPrimes = new int[]{17,19,23,29,31,37};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

这是下列语句的简写形式(只是少了一个annoymous的变量):

int[] annoymous = {17,19,23,29,31,37};
smallPrimes = annoymous;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

注释:在Java中,允许数组长度为0。在编写一个返回结果为数组的方法时,如果碰巧结果为空,则这种语法形式就显得非常有用。此时可以创建一个长度为0的数组。

new elementType[0];

注意,数组长度为0null不同;

class Demo2
{
	public static void main(String[] args)
	{
		int[] elementType = new int[0];
		System.out.println(elementType.length); 
	}
}

程序运行结果:

0

数组初始化的注意事项:

  1. 在赋值符号 = 的右边没有new运算符,也不说明数组的长度,系统会根据所赋初值的个数自动计算数组的长度
  2. 数组的初始化赋值必须把所有初值数组的声明写在同一个语句里,如果分开则会出错。以下的写法时错误的。
int[] array;
array = {10,20,30,40,50};

数组拷贝

Java中,允许将一个数组变量拷贝给另一个数组变量。这时,两个变量将引用同一个数组,即==两个数组名指向同一块内存空间==,而不是两块不同的空间。例如:

int[] luckyNumbers = smallPrimes;
luckyNumbers[5] = 12;//现在smallPrimes[5]也是12

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

图片显示了拷贝的结果。如果希望将一个数组的所有值拷贝到一个新的数组中去(即在内存中是两块不同的内存空间),就要使用Arrays类的copyOf()方法;
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
2个参数是新数组的长度,这个方法通常用于来增加数组的大小

import java.util.Arrays;
class Demo2
{
	public static void main(String[] args)
	{

		int[] smallPrimes = {17,19,23,29,31,37};
		int[] luckyNumbers = smallPrimes;
		luckyNumbers[5] = 12;
		int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length);
		for (int i : copiedLuckyNumbers) {
			System.out.println(i);
		}
	}
}

程序运行结果:

17
19
23
29
31
12

C++注释:Java数组与C++数组在堆栈上有很大的不同,但基本上与分配在堆(heap)上的数组指针一样。也就是说,
int[] a = new int[10];//Java
不同于
int a[10];//C++
而等同于
int* a = new int[10]; //C++
Java中的[]运算符被预定义为检查数组边界,而且没有指针运算,即不能通过a1得到数组的下一个元素。

数组的length属性

Java可以使用运算符"."和length属性可以得到数组的长度。
例如:

int[] arr = new int[20];
int len = arr.length;  //len = 20;

经常使用数组的length属性得到数组元素的个数,配合循环语句对数组进行遍历或者其他操作

数组排序

要想对数值型数组进行排序,可以使用Arrays类中的sort方法Arrays.sort(数组名)
Arrays.sort(arr)
这个方法使用了优化的快速排序算法。快速排序算法对于大多数数据集合来说都是效率比较高的。Arrays类还提供了几个使用很便捷的方法,稍后的API注释会介绍。
例如

import java.util.Arrays;
class Demo2
{
	public static void main(String[] args)
	{
		int[] arr = new int[10];
		for(int i= 0; i < arr.length; i++)
		{
			arr[i] = (int)(Math.random()*100);  //为arr数组随机赋值
		}
		System.out.println(Arrays.toString(arr));  //打印arr数组
		Arrays.sort(arr);  //调用sort方法为arr数组排序s
		System.out.println(Arrays.toString(arr));
	}
}

程序运行结果:

[75, 88, 39, 91, 71, 87, 72, 19, 14, 13]
[13, 14, 19, 39, 71, 72, 75, 87, 88, 91]

该程序用到了数组,Math.random()方法将返回一个 0 − 1 0-1 01之间(包含 0 0 0、不包含 1 1 1)的随机浮点数。用 n n n乘以这个浮点数,就可以得到从 0 ~ n − 1 0~n-1 0n1之间的一个随机数。

arr[i] = (int)(Math.random()*100);  //arr[i]结果为0~99的随机整数值
  1. static String toString(type[] a)
    返回包含a中数据元素的字符串,这些数据元素被放在括号内,并用逗号分隔。
  1. static type copyOf(type[] a, int length)
  2. static type copyOfRange(type[] a, int start, int end)
    返回与a类型相同的一个数组,长度为length或者end-start,数组元素为a的值。
    参数:a 类型为int、long、short、char、byte、boolean、floatdouble的数组。
    start 起始下标(包含这个值)
    end 终止下标(不包含这个值)。这个值可能大于a.length,结果为0false
    否则,数组中只有前面length个数组元素的拷贝值。
  3. static void sort(type[] a)
    采用优化的快速排序算法 对数组进行排序
    参数:a类型为int、long、short、char、byte、boolean、float或者double的数组。
  4. static int binarySearch(type[] a, type v)
  5. static int binarySearch(type[] a, int start, int end, type v)
    采用二分搜索算法查找值v。如果查找成功,则返回相应的下标值;否则,返回一个负数值r-r-1是为保持a有序v应插入的位置。
    参数:a 类型为int、long、short、char、byte、boolean、floatdouble的数组。
    start起始下标(包含这个值)
    end 终止下标(不包含这个值)。
    va的数据元素的类型相同。
  6. static void fill(type[] a, type v)将数组的所有数据元素设置为v;
    参数a:类型为int、long、short、char、byte、boolean、floatdouble的数组。
    va数据元素类型相同的一个值。
  7. static boolean equals(type[] a, type[] b)
    如果两个数组大小相同,并且下标相同的元素都对应相等,返回true
    参数ab:类型为int、long、short、char、byte、boolean、floatdouble的数组。
import java.util.Arrays;
class Demo2
{
	public static void main(String[] args)
	{
		int[] arr = new int[10];
		int[] brr = new int[10];
		for(int i= 0; i < arr.length; i++)
		{
			arr[i] = (int)(Math.random()*100);
		}
		System.out.println(Arrays.toString(arr));
		Arrays.sort(arr);
		System.out.println(Arrays.toString(arr));
		brr = Arrays.copyOf(arr,arr.length);
		System.out.println(Arrays.toString(brr));
		Arrays.fill(brr, 10);
		System.out.println(Arrays.toString(brr));
		System.out.println(Arrays.equals(arr, brr));
		Arrays.fill(arr,10);
		System.out.println(Arrays.equals(arr, brr));
	}
}

程序运行结果:

[66, 17, 24, 66, 81, 53, 11, 40, 32, 2]
[2, 11, 17, 24, 32, 40, 53, 66, 66, 81]
[2, 11, 17, 24, 32, 40, 53, 66, 66, 81]
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
false
true

###多维数组
多维数组将使用多个下标访问数组元素,它适用于表示表格或更加复杂的形式。对于一个数值表,可以使用一个**二维数组(也称为矩阵)**存储这些信息。
Java中,声明一个二维数组相当简单。例如:
double[][] arr;
与一维数组一样,在调用new对多维数组进行初始化之前不能使用它。在这里可以这样初始化:
arr = new double[ROW][COLUMN];
另外,如果知道数组元素,就可以不调用new,而直接使用简化的书写形式对多维数组进行初始化。例如:

		 int[][] magicSquare = 
		{
			{16,3,2,13},
			{5,10,11,8},
			{9,6,7,12},
			{4,15,14,1}
		};	

一旦数组被初始化,就可以利用两个方括号访问每个数组,例如,magicSquare[i][j];

注释:foreach循环语句不能自动处理二维数组的每一个元素。它是按照行,也就是一维数组处理的。要想访问二维数组a的所有元素,需要使用两个嵌套的循环,如下所示:

for (int[] row: a) 
		{
			for (int value : row) 
			{
				do something with value;
			}
		}

不规则数组

到目前为止,读者所看到的数组与其他程序设计语言提供的数组没有多大区别。但实际存在着一些细微的差异。而这正是Java的优势所在:Java实际上没有多维数组,只有一维数组。多维数组被解释为"数组的数组"
例如,int arr[10][6];arr数组实际上是一个包含 10 10 10个元素的数组,而每个元素又是一个由 6 6 6个整数组成的数组,如图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传在这里插入图片描述

表达式arr[i]引用第i+1个子数组,也就是二维表的第i+1行。它本身也是一个数组arr[i+1][j+1]引用这个数组的第j项,
由于可以单独地存储数组的某一行,所以可以让两行交换

int[] temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;

还可以方便的构造一个"不规则"数组,即数组的每一行有不同的长度

import java.util.Arrays;
class DemoJava
{
	public static void main(String[] args)
	{
		final int MAX = 10;
		
		int[][] odds = new int[MAX+1][];
		for (int n = 0; n <= MAX; n++) 
		{
			odds[n] = new int[n+1];
		}
		
		for(int n = 0; n < odds.length; n++)
		{
			for (int k = 0; k < odds[n].length; k++) 
			{
				int lotteryOdds = 1;
				for (int i = 1; i <= k; i++) 
				{
					lotteryOdds = lotteryOdds * (n - i +1)/i;
				}
				odds[n][k] = lotteryOdds;
			}
		}	
		for (int[] row: odds) 
		{
			for (int odd : row) 
			{
				System.out.printf("%4d",odd);
			}
			System.out.println();
		}
	}
}

程序运行示例:

   1
   1   1
   1   2   1
   1   3   3   1
   1   4   6   4   1
   1   5  10  10   5   1
   1   6  15  20  15   6   1
   1   7  21  35  35  21   7   1
   1   8  28  56  70  56  28   8   1
   1   9  36  84 126 126  84  36   9   1
   1  10  45 120 210 252 210 120  45  10   1
 252 210 120  45  10   1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ocodotial

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值