Java程序设计 7 数组

什么是数组

数组(array)是相同类型变量集合( 这里的集合 不是JDK的Collection )
数组类型的变量是 引用相同类型变量集合的引用变量

java 复制代码
double[] myList = new double[10];

凡使用new后,内存单元都初始化为 0(值)或 null(引用)

数组元素本身也可以是引用变量。

java 复制代码
double[][] myList = new double[4][]; 		//创建一个二维数组
myList[0]=new double[2];		 // myList[0]是一个引用变量,指向一个一维数组(2个元素)
myList[3]=new double[3];		// myList[3]是一个引用变量,指向一个一维数组(3个元素)

多维数组只是数组的数组,故数组元素也可能是引用类型变量,**这就让Java中的多维数组的低一维的数组长度不必相同,**这是与C/C++的区别。

声明一维数组引用变量

任何实例化的数组都是Object的子类。数组引用变量声明语法:

datatype[] arrayRefVar ; // 提倡的写法:类型在前,[]在后

例如:double[] myList; //这时myList为null

或者:datatype arrayRefVar[];

例如:

java 复制代码
double myList[];
double [] a[];   //double[][] a;

数组变量是引用类型的变量声明数组引用变量并不分配数组内存空间必须通过new实例化数组来分配数组内存空间。

创建数组-new

使用new 操作符创建数组。
arrayRefVar = new datatype [arraySize];
例如:myList = new double[10]; // 这时才分配内存
声明和创建在一条语句中: datatype[ ] arrayRefVar = new datatype[ arraySize ] ;
或 datatype arrayRefVar [] = new datatype[ arraySize ] ;
例如:double[] myList = new double[10];或者:double myList[] = new double[10];

数组元素的初始化

新创建的数组对象,其元素根据类型被设置为默认的初始值(实际上都为0)。

数值类型为 0
字符类型为 '\u0000' ,u后面为十六进制, 必须4位写满
布尔类型为 false
引用类型为 null
数组可以在声明后的花括号中提供初始值。

java 复制代码
double[] myList = {1.9, 2.9, 3, 3.5}//可以将int转化为double类型,这时不用指定维度size

或者

java 复制代码
double[] myList;
myList = new double[] {1.9, 2, 3.4, 3.5} 
//可以将int转化为double类型,声明和创建不在一条语句时,不能直接用{}来初始化

访问数组

数组的大小 在创建这个数组之后不能被改变 。用以下语法访问数组的长度
arrayRefVar.length
数组元素通过索引进行访问。 元素的索引从0开始,范围从0到length-1。
arrayRefVar[index]

示例代码:

java 复制代码
public class TestArray {
	public static void main(String[ ] args) {/** Main method */
		final int TOTAL_NUMBERS = 6;
		int[] numbers = new int[TOTAL_NUMBERS];
		// Read all numbers
		for (int i = 0; i < numbers.length; i++) {
			String numString = JOptionPane.showInputDialog("Enter a number:");
			numbers[i] = Integer.parseInt(numString);
		}
		// Find the largest
		int max = numbers[0];
		for (int i = 1; i < numbers.length; i++) {
			if (max < numbers[i])  	max = numbers[i];
		}
		System.out.println("Max number is " + max);
	}
}

数组的复制

直接使用赋值语句不能实现数组复制,结果是两个数组引用变量指向同一个数组对象(浅拷贝赋值)。

复制数组的方法

  • 使用循环来复制每个元素
java 复制代码
int[ ] sourceArray = {2,3,1,5,10};
int[ ] targetArray = new int[sourceArray.length];
for(int i = 0; i < sourceArray.length; i++){
	targetArray[i] = sourceArray[i];//=赋值对引用类型是浅拷贝
}
  • 使用System.arraycopy方法:两个数组都预先实例化了
java 复制代码
//System.arraycopy方法: sourceArray, targetArray都已经实例化好
//arraycopy(sourceArray,srcPos,targetArray,tarPos,length);
System. arraycopy(sourceArray,0,targetArray,0, sourceArray.length);//target要求已存在

src:源数组,可以是任意类型的数组对象。

srcPos:源数组中的起始位置,从这个位置开始复制元素。

dest:目标数组,也是一个任意类型的数组对象,用于接收复制的元素。

destPos:目标数组中的起始位置,从这个位置开始插入元素。

length:要复制的元素个数。

  • 调用数组的clone方法复制:被复制的数组变量可以没有实例化
java 复制代码
int[] targetArray= sourceArray.clone();

将数组传递给方法

基本数据类型传递的是实际值的拷贝,修改形参,不影响实参。

数组引用变量传递的是对象的引用,修改形参引用的数组,将改变实参引用的数组, 也可以从方法中返回数组,返回的也是引用。

java 复制代码
public class TestPassArraySimple{
	/** Main method */
	public static void main(String[ ] args) {
		int x =1;
		int[ ] y = new int[10];
		y[0] = 20;

		m(x, y);
		System.out.println("x is " + x);
		System.out.println("y[0] is " + y[0]);
	}
	public static void m(int number, int[ ] numbers) {
		number = 1001;       //不改变x的值:值参传递
		numbers[0] = 5001; //改变y[0]
	}
}

String、Integer这样的对象作为参数传递

java 复制代码
public class CallByReferenceException {
    public static void main(String[] args) {
	    Integer x = Integer.valueOf(10);
	    testInteger(x);
	    System.out.println("x = " + x);

	    String y = "ABC";
	    testString(y);
	    System.out.println("y = " + y);
    }
    public static void testInteger(Integer i) {
	    i = 20;
	    System.out.println("i = " + i);
    }
    public static void testString(String s) {
	    s = "abc";
	    System.out.println("s = " + s);
    }
}

输出:

i = 20

x = 10

s = abc

y = ABC

引用类型的实参传递给形参后,实参、形参指向同一个对象。

但对于String 基本数据类型的包装类型的实参传递给形参,形参变了不会导致实参变化。这是因为String、Integer的内容是不可更改的,在Integer内部,用private final int****value 来保存整数值,在String内部,用**private final char value[]**来保存字符串内容。

对于String、Integer这样内容不可改变的对象,当对其赋值时实际上创建了一个新的对象。

为什么这么设计?

以Integer为例,因为Integer是int的包装类,它必须要和int的特性一致:int作为方法参数调用时,方法内部对参数的改变不会影响实参。所以Integer必须这么设计

从方法中返回数组

调用方法时,可向方法传递数组引用,也可从方法中返回数组引用

java 复制代码
//下面的方法返回一个与输入数组顺序相反的数组引用
public static int[] reverse (int[] list){
	int[] result = new int [list.length];
     for(int i = 0, j = result.lenght - 1; i < list.length; i++,j--){
			result [j] = list [i];
	}
	return result;
}
int[] list1 = {1, 2, 3, 4, 5, 6};
int[] list2 = reverse(list1);

可变长参数列表

可以把类型相同但个数可变的参数传递给方法。

方法中的可变长参数声明如下:

java 复制代码
typeName ... parameterName

在方法声明中,指定类型后面跟省略号
只能给方法指定 一个 可变长参数,同时 该参数必须是最后一个参数
Java将 可变长参数当数组看待 ,通过 length 属性得到可变参数的个数

java 复制代码
print(String... args){   //可看作String []args
    for(String  temp:args)
        System.out.println(temp);
    System.out.println(args.length);
}
//调用该方法:
print("hello","lisy");

Arrays类

java.util.Arrays类包括各种静态方法,其中实现了数组的排序和查找

排序

java 复制代码
double[] numbers={6.0, 4.4, 1.9, 2.9};
java.util.Arrays.sort(numbers); //注意直接在原数组排序

二分查找

java 复制代码
int[ ] list={2, 4, 7, 10, 11, 45, 50};
int index = java.util.Arrays.binarySearch(list, 11);

命令行参数

可以从命令行向java程序传递参数。参数以空格分隔,如果参数本身包含空格,用双引号括起来。格式:

java 类名 参数1 参数2 ...

例如:java TestMain "First number" alpha 53

命令行参数将传递给main方法的args参数。args是一个字符串数组,可以通过数组下标访问每个参数。

public static void main(String[] args)

注意Java的命令行参数不包括类名, args.length**== 3**

可变长参数用...定义。args是一个字符串数组,可以定义为可变长参数。String ... args可以当成String[ ] args数组使用。

public static void main(String ... args) //也可以作为启动函数

注意在定义重载函数时,编译器认为String[] args和String ... args类型相同

多维数组

二维数组:数组的数组

声明二维数组引用变量:dataType[][] refVar;

创建数组并赋值给引用变量:当指定了行、列大小,是矩阵数组 (每行的列数一样)。非矩阵数组则需逐维初始化

refVar = new dataType[rowSize][colSize]; (这时元素初始值为0或null)

在一条语句中声明和创建数组

dataType[][] refVar = new dataType[rowSize][colSize];

或者:dataType refVar[][ ] = new dataType[rowSize][colSize];

二维数组的每个元素是一个一维数组。int[][] X =new int[3][4];

X指向的是内存里的一个一维数组,数组X的长度是数组X的元素的个数,可由X.length得到,X.length = 3。

元素X[i]是引用,指向另一个一维数组,其长度可由X[i].length得到。

X.length是final的,不可修改。

不规则数组

二维数组每一行的列数可以不同。

创建不规则二维数组时,可以只指定第一维下标。这时第一维的每个元素为null(如下所示),必须为每个元素创建数组。例如:

java 复制代码
int[][] x = new int[5][];  //第一维的每个元素为null
x[0] = new int[5];//为每个元素创建数组
x[1] = new int[4];
x[2] = new int[3];
x[3] = new int[2];
x[4] = new int[1];
//x.length=5
//x[2].length=3
//x[4].length=1 ,只能取x[4].length的值(它是final的)
相关推荐
Chrikk3 分钟前
Go-性能调优实战案例
开发语言·后端·golang
亦枫Leonlew4 分钟前
三维测量与建模笔记 - 3.3 张正友标定法
笔记·相机标定·三维重建·张正友标定法
幼儿园老大*6 分钟前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue6 分钟前
go语言连续监控事件并回调处理
开发语言·后端·golang
考试宝8 分钟前
国家宠物美容师职业技能等级评价(高级)理论考试题
经验分享·笔记·职场和发展·学习方法·业界资讯·宠物
杜杜的man9 分钟前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟10 分钟前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity1 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天1 小时前
java的threadlocal为何内存泄漏
java
caridle1 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express