数组
一:数组的特殊性
在Java中数组是一种效率最高的储存和随机访问对象引用序列的方式。数组是一个简单的线性序列,使得元素访问非常快速,但是为速度付出的代价是,数组对象的大小被固定,且在其生命周期中不可改变。
数组可以持有基本类型,而泛型之前的容器则不能。。但有了泛型及自动包装机制,容器也能够持有基本类型,数组仅剩下效率的优点了。
二:数组是第一级对象
- 无论是使用基本类型的数组还是引用类型的数组,数组标识符都只是一个引用,指向堆中创建的第一个真实对象,这个(数组)对象用于保存指向其他引用的对象。
- 只读成员length是数组对象的一部分,这是唯一一个可以访问的字段和方法,且表示的是数组的大小而不是数组保存的元素个数。
- 新生成一个数组对象时,其中的引用被自动初始化为null。对于基本类型,若为数值型则初始化为0;对于char类型,则初始化为(char)0;若为布尔型,则默认初始化为false。
三:多维数组
创建多维数组很方便,可以通过new关键字,也可以通过{ }将每个花括号分隔开(每对花括号括起来的集合都会把你带到下一级数组)。
使用花括号创建
如:
int [][] a = {
{1,2,3,},
{4,5,6,},
}
int [][] b ={ //这类数组被称为粗糙数组,数组中构成矩阵的的每个向量都可以具有任意的长度
{1,2,},
{3,4,8,},
{7,8,9,1,40,25,},
}
使用new关键字创建
如:
int [][][] a = new int [2][2][4];
//这类数组被称为粗糙数组,数组中构成矩阵的的每个向量都可以具有任意的长度
int [][][] b = new int [rand.nexInt(10)][][];
打印多维数组
Arrays.deepToString(arrayName):打印数组中的值,对引用类型及基本类型都适用。
四:Arrays实用功能
在java.util类库中的Arrays类中有一些基本的常用的static方法:
- equals():用于比较二个数组是否相等
- deepEquals:用于比较多维数组
- fill() :适合于把数组用同一个值或不同值(采用随机数Random)初始化
- sort():对数组排排序
- binarySearch():在已排好序的数组中查找元素。若未排序后果自负。
- toString():产生数组的string表示
- deepToString():多维数组的打印
- hashCode():产生数组的散列码
- Arrays.asList():接受序列或数组作为参数,将一个数组转化为一个List对象,这个方法会返回一个ArrayList类型的对象, 这个ArrayList类并非java.util.ArrayList类,而是Arrays类的静态内部类!用这个对象对列表进行添加删除更新操作,就会报UnsupportedOperationException异常。本质上仍是一个数组。
复制数组System.arrayCopy()
注意:System.arrayCopy()这个方法并不属于Arrays类,复制数组的速度很快。且copy的二个数组必须具有相同的确切类型(不会进行自动包装/拆包)。
如果复制对象数组,其实只是复制了对象的引用——而不是对象本身的拷贝。
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,int length);
arraycopy(Object src, int srcPos,Object dest, int destPos,int length)的参数意义:
- args0:源数组即提供复制所需元素的数组
- args1:从源数组的哪个下标开始提供复制所需的元素
- args2:目标数组
- args3:从目标数组的什么位置接受复制的元素
- args4:需要复制元素的个数
数组复制的几种方法效率比较
效率:System.arraycopy > clone > Arrays.copyOf > for循环
- for循环
for循环的话,效率最低.
- System.arrycopy()
System.arraycopy()源码中可以看到是native方法:native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。 可以将native方法比作Java程序同C程序的接口。
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,int length);
- Arrays.copyOf()
从源码中可以看到本质上是调用的arraycopy方法。,那么其效率必然是比不上 arraycopy的。
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
- 使用clone方法
clone()的完整定义:protected native Object clone() throws CloneNotSupportedException;只有Object[]数组的clone()方法才返回Object类型,子类重写了父类的方法。
而clone()和System.arraycopy只是从实验的结果来看是System.arraycopy的效率高。
数组的比较
Arrays提供了重载后的equals()方法,用于比较整个数组。 数组相等的条件必须是元素个数必须相等,并且对应位置的元素也相等。
在已排序的数组中查找元素
Arrays.binarySearch()若找到了目标元素返回目标元素在数组中的位置(>=0),若未找到则返回负值。
若数组中有重复元素,无法保证找到的元素是副本中的哪一个。
总结:在使用时应优先选用容器而不是数组,只有当确定在使用数组时性能会提高才使用。