查询/查找/检索 某个下标上的元素时效率极高,可以说是查询效率最高的一个数据结构。
数组中存储100个元素,或者100w个元素,在元素查询/检索方面,效率相同,因为数组中元素查找的时候不会一个一个的找,是通过数学表达式计算出来的。(算出一个内存地址,直接定位)
由于为了保证数组中每个元素的内存地址连续,所以在数组上随机删除或者增加元素时(非末尾元素),效率较低,因为随机增删元素会涉及到最后元素统一向前或者向后位移操作。
数组不能存储大数据量,为什么? 因为很难在内存空间上找到一块特别大的连续内存空间。
注意 对于数组中最后一个元素的增删,是没有效率影响的。
语法格式:
int[] array1;
double[] array2;
boolean[] array3;
静态初始化语法格式:
int[] array = {100,232,343};
动态初始化语法格式:
int[] array = new int[5]; // 这里的5 表示数组的元素个数。
// 初始化一个5个长度的int类型数组,每个元素会赋值默认0
String[] names = new String[5];// 初始化一个6个长度的String类型数组,每个元素默认null
什么时候采用静态初始化方式?什么时候使用动态初始化方式?
当你创建数组的时候,确定数组中存储哪些具体的元素时,采用静态初始化方式。
当你创建数组的时候,不确定将来数组中存储哪些数据,你可以采用动态初始化的方式,预先分配内存地址
对于数组来说,实际上只能存储java对象的"内存地址" 。 数组中存储的每个元素是"引用"
在java 开发中,数组长度一旦确定不可变。那么数组满了怎么办?
先新建一个大容量的数组,然后将小容量数组中的数据一个一个拷贝到大容量的数组中
数组扩容 效率较低,因为涉及到拷贝的问题,所以在以后的开发中请注意: 尽可能少的进行数组的拷贝。 可以在创建数组对象的时候预估以下多长合适,最好预估准确,这样可以减少数组扩容次数,提高效率
public class ArrayTest01 {
public static void main(String[] args) {
//声明一个int 类型的数组, 使用静态初始化的方式
//java风格
int[] a1 = {1,100,10,20,55,689};
//c++风格
// int a1[] = {1,100,10,20,55,689};
//所有的数组对象都有length属性
System.out.println(a1.length);
//数组中每个元素都有下标
//通过下标对数组的元素进行存/取
//取(读)
System.out.println("第一个元素="+a1[0]);
System.out.println("最有一个元素="+a1[a1.length-1]);
//存(改)
//把第一个元素改为 123
a1[0]=123;
//把最后一个元素改为 0
a1[a1.length-1]=0;
System.out.println("第一个元素="+a1[0]);
System.out.println("最有一个元素="+a1[a1.length-1]);
//一维数组遍历
for(int i=0; i<=a1.length-1;i++){
System.out.println(a1[i]);
}
//数组越界异常 java.lang.ArrayIndexOutOfBoundsException
// System.out.println(a1[6]);//
// 动态初始化
Object[] ob = new Object[3];
for(int i=0; i<=ob.length-1;i++) {
System.out.println(ob[i]);
}
//存储Object,采用静态初始化
Object ob1 = new Object();
Object ob2 = new Object();
Object ob3 = new Object();
Object[] obs = {ob1,ob2,ob3};
System.out.println(obs);
for(int i=0; i<=obs.length-1;i++) {
System.out.println(obs[i]);
}
System.out.println("=============");
printArray(a1);
System.out.println("*************");
printArray(new String[5]);
System.out.println("++++++++++++++");
printArray(new int[]{23,334,56});
System.out.println(args.length);
System.out.println("ttttttttttt");
// 创建一个Animal类型的数组,里面存储了cat 和Bird
Animal[] animals = {new Cat(),new Bird()};//该数组中存储了两个对象的内存地址
for (int i = 0; i<animals.length;i++){
//从animals中取出来的可能是Cat,也可能是Bird 不过肯定是一个Animal
// 如果调用的方法是父类中存在的方法不需要向下转型,直接使用父类型引用即可
// Animal an = animals[i];
// an.move();
animals[i].move();
if (animals[i] instanceof Bird){
Bird bird = (Bird)animals[i];
bird.sing();
}
//数组拷贝
//System.arraycopy(5个参数)
//拷贝源(从这个数组中拷贝)
int[] aa1 = {1,100,10,20,55,689};
// 拷贝目标 (拷贝到这个目标数组上)
int[] dest = new int[10];//动态初始化一个长度为10的数组
//调用System.arraycopy() 拷贝aa1 中的 第2,3 元素到 dest的3,4位置上
System.arraycopy(aa1,1,dest,2,2);
//循环输出
for(int t=0; t<dest.length;t++) {
System.out.println(dest[t]);
}
System.out.println("————————————————————");
//数组中如果存储的元素是引用,可以拷贝吗? 当然可以
Object[] obj = {new Object(),new Object(),new Object()};
Object[] newObj = new Object[10];
// 思考: 这里拷贝的时候,拷贝的是对象还是对象地址? (地址)
//将obj数组中所有的元素全部拷贝到newObj中
System.arraycopy(obj,0,newObj,0,obj.length);
for(int t=0; t<newObj.length;t++) {
System.out.println(newObj[t]);
}
}
}
public static void printArray(int[] array){
for(int i=0; i<=array.length-1;i++) {
System.out.println("int数组: "+array[i]);
}
}
public static void printArray(String[] args){
for(int i=0; i<=args.length-1;i++) {
System.out.println("String 数组中的元素: "+args[i]);
}
}
}
class Animal{
public void move(){
System.out.println("move");
}
}
class Cat extends Animal{
public void move(){
System.out.println("Cat");
}
}
class Bird extends Animal{
public void move(){
System.out.println("Bird");
}
public void sing(){
System.out.println("Bird sing");
}
}