数组
- 数组是一种引用数据类型,父类是Object
- 数组当中可以存基本数据类型,也可以存储引用数据类型的数据
- 数组当中如果存的是对象,实际存的是对象的引用,即内存地址
- 数组是存储在堆内存中的
- 数组自带length属性,获取数组长度
- 数组一经定义,长度不可变
- 数组中的元素类型统一(有时候会见到Animal[] animal = {new Cat(),new Bird()},其实是子转父,自动转。数组中元素类型仍然是Animal)
- 查询/查找/检索某个下标上的元素时效率极高。
- 数组中的元素(即a[0],a[1]…)内存地址连续
优点
每一个元素的内存地址在空间上存储是连续的
每一个元素类型相同,所以占用空间大小一样
- 知道第一个元素内存地址,知道每一个元素占用空间的大小,又知道下标,所以通过一个数学表达式就可以
计算出
某个下标上元素的内存地址。直接通过内存地址定位元素
,所以数组的检索效率最高。
数组中存储100个元素和存储100万个元素,效率是一样的,因为它不是一个一个找元素的,是通过数学表达式计算出来的。(算出来一个内存地址,直接定位)
缺点
- 由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或增加元素的时候,效率较低,因为随机增删元素会涉及到后面的元素统一前移或者统一后移操作,但是在数组的最后进行删和增时,不牵扯到其他元素的前移和后移,所以效率不受影响。
总结这句话:数组增删在牵扯到其他元素后移/前移时,效率较低。
数组不能存储大数据量
,因为很难在内存空间上找到一块特别大的连续的内存空间。(因为内存空间可能被其他存在堆内存中的对象占用掉,其他存在堆内存中的对象又不一定是连续的)
语法
//初始化:
//静态
int array[] = {100,200,300};
//动态
int array[] = new int[5];//初始化一个5个长度的int类型数组,每个元素默认0;
String names[] = new String[6];//初始化一个6个长度的String类型数组,每个元素默认null;
main方法上的String[] args
JVM调用main方法的时候,会自动传一个String 数组过来,JVM默认传递过来的这个数组对象非空,其长度为0,即数组内没有元素。
但是:
这样运行:java XXX 123 xyz kkk hahah (XXX是XXX.class的名字)
那么这个时候JVM会自动将"123 xyz kkk hahah" 通过空格的方式进行分离,分离完成后,自动放入"String[] args" 数组里。所以main方法上面的String[] args 数组主要是用来接收用户输入参数的。遍历args 即 {“123”,“xyz”,“kkk”,“hahah”}
eg.
模拟一个系统,假设这个系统要使用,必须先输入用户名和密码。
可以把用户名和密码放进String[] args里,判断。
java XXX 用户名 密码
数组的扩容
建一个大的数组,把小的数组中的元素一个一个copy进大数组中。
数组扩容效率低,涉及copy,尽量少的进行数组的copy。
数组的拷贝
- System.arraycopy(原数组,原数组要拷贝元素的下标,目标数组,目标数组存放拷贝元素的起始位置,拷贝元素的个数)
即 代替了 循环挨个儿赋值
//基本类型
public static void main(String[] args) {
float[] l = {1, (float) 12.5, 45.6F};
float[] s = new float[10];//新数组开辟了空间,像是深克隆
System.arraycopy(l, 1, s, 5, 2);
for (int i = 0; i < s.length; i++) {
System.out.print(s[i]);
}
float[] x = s;//直接赋,像是浅克隆
//两种copy的区别:
System.out.println(l+"...."+s);
System.out.println(x+"...."+s);
}
/*output :
0.0 0.0 0.0 0.0 0.0 12.5 45.6 0.0 0.0 0.0
[F@20e2cbe0....[F@68be2bc2
[F@68be2bc2....[F@68be2bc2
*/
//引用类型
public static void main(String[] args){
Object object[] = {new Object(),new Object(),new Object()};
Object object2[] = new Object[5];//新数组开辟了空间,像是深克隆
System.arraycopy(object, 0, object2, 1, 3);
Object[] object3 = object2;//直接赋,像是浅克隆
for(int i = 0;i<object2.length;i++){
System.out.print(object2[i]+" ");
}
//两种copy的区别:
System.out.println(object+"----"+object2);
System.out.println(object3+"----"+object2);
}
/* output :
null java.lang.Object@51081592 java.lang.Object@7f9a81e8 java.lang.Object@9629756 null
[Ljava.lang.Object;@675d3402----[Ljava.lang.Object;@51565ec2
[Ljava.lang.Object;@51565ec2----[Ljava.lang.Object;@51565ec2
*/