数组与其他种类的容器之间的区别有三方面:效率、类型和保存基本类型的能力。
在Java中数组是一种效率最高的存储和随机访问对象引用序列的方式。
数组就是一个简单的线性序列,这使得元素访问非常快速。但是为这种速度所付出的代价是数组对象的大小被固定,并且在其生命周期中不可改变。
泛型的出现使得容器也具备了类型检查的能力,而自动装箱机制使容器可以与数组几乎一模一样的用于基本类型,数组的硕果仅存的优点就是效率。
数组之所以优于泛型之前的容器,就是因为可以创建一个树去持有某种基本类型,意味着可以通过编译期检查,防止插入错误类型和抽取不当类型。
对象数组保存的是引用,基本类型数组保存的是值。
在声明数组时可采用“聚集初始化”方法:
int[] integers = {0, 1, 2, 3, 4};
但是如果不在声明时初始化则必须采用“动态聚集初始化”方法:
int[] integers;
integers = new int[] {0, 1, 2, 3, 4};
基本类型:数值型初始化为0,char型初始化为 (char)O,boolean型初始化为false。
对象类型:初始化为null。
与C++不同,Java可以返回一个数组
Java 1.5新增的Arrays.deepToString()方法可以将多维数组转换为可读的String。
数组中构造矩阵的每个向量都可以具有任意的长度,这被称为粗糙数组。
如:
a[][] = {{{}, {0} }, {{0,0}, {0,0,0}, {0,0,0,0,0}},{{0}} }
自动包装机制对数组初始化器也起作用。
数组和泛型不能很好的结合,因为数组必须知道它所持有的确切类型,以强制保证类型安全。
不能实例化具有泛型参数类型的数组:
Peel
如果确定将来不会向上转型,并且需求相对简单,那么可以创建泛型数组。但是泛型容器总是比泛型数组更好的选择。
List[] ls;
List[] la = new List[20];
ls = (List[])la;
ls[0] = new ArrayList();
//erro
//ls[1] = new ArrayList();
Object[] objects = ls;
objects[1] = new ArrayList();
Java标准类库Arrays有一个作用十分有限的fill()方法,只能用同一个值填充各个位置,针对对象而言,就是复制同一个引用进行填充,还可以只填充数组的某个区域:
填充数组,如
double[] a = new double[5];
Arrays.fill(a,1.0);
String[] b = new String[7];
Arrays.fill(b,3,5,"Feynman");
六个基本功能:
Java标准类库提供static方法System.arraycopy(),用它复制数组比用for循环复制快很多。
System.arraycopy(Object src, int srcPosition, Object dest, int destPosition, int length);
基本类型数组与对象数组都可以复制。如果复制对象数组,只是复制了对象的引用——而不是对象本身的拷贝,这被称为浅复制。System.arraycopy()不会执行自动包装盒自动拆包,两个数组必须具有相同的确切类型。
想到条件:元素个数相等,元素内容相等。
Arrays类提供了静态equals()方法,用来比较整个数组。数组相等的条件是元素个数必须相等,并且对应位置的元素也相等,通过对每一个元素使用equals()方法来作比较。
使用Arrays.deepEquals()可以比较多维数组。
使用静态方法Arrays.sort()用语对数组进行排序。
Java有两种方式来提供比较功能:
1.实现java.lang.Comparable接口,覆写其compareTo()方法。如果没有实现Comparable接口,调用sort()会抛出ClassCastException异常。
2.不可能总改变类的接口或者修改其代码,更灵活的是 需要比较时,创建一个实现Comparable接口的类。这是策略设计模式的一个应用实例。这个类有两个方法compare()和equals()方法。不一定要实现equals()方法,因为它间接的继承自Object的equals()方法。
Collections类包含一个reverseOrder()静态方法可以产生一个Comparator,它可以翻转自然的排序顺序。
String的排序算法依据词典编排顺序排序,所以大写字母开头的词都放在前面,然后是小写字母。
如果想一起排序,就String.CASE_INSENSITIVE_ORDER。如:Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
对于已经排序好的数组,使用Arrays.binarySearch()快速查找,必须是对排序好的数组才可使用。
如果要对未排序的数组使用binarySearch()将产生不可预料的结果(可能指没找到元素的返回情况)。
如果在数组中找到要找的值,返回该值所在位置的索引,如果未找到,则返回负值,其计算方式是 -(插入点)-1,插入点指第一个大于该元素的数所在的位置。
如 对数组{1,2,4,5}查找3,那么返回 - 2-1 = -3
如果需要对没有重复元素的数组排序可以使用TreeSet(保持排序顺序),或者LinkedHashSet(保持插入顺序)。这些类会自动处理所有细节。除非他们成为程序性能的瓶颈,否则不需要自己维护数组。
如果使用Comparator排序了某个对象数组,在使用binarySearch()时必须提供同样的Comparator。
使用新版本的Java时,优选容器而不是数组。只有在已证明性能成为问题(并且切换到数组对性能提高有所帮助)时,才应该将程序重构为使用数组。