文章目录
16.1 数组为什么特殊
数组与其他种类的容器之间的区别:
(1)效率。数组是一个简单的线性序列,这使得元素访问非常快速,代价是数组对象的大小被固定。ArrayList通过创建一个新实例,然后把旧实例中所有引用移到新实例中,从而实现更多空间的自动分配,但效率比数组低很多。
(2)可以持有具体类型。在泛型之前,其他容器类在处理对象时,会将对象都当作Object。而数组可以持有某种具体类型,即通过编译器检查防止插入错误类型。
(3)保存基本类型的能力。数组可以持有基本类型,而泛型之前的容器则不能(现在可以指定并检查持有的元素,还有了自动包装机制)。
注:数组和容器类现在都有类型检查,区别是数组使用[]来访问元素,而List使用的是add()和get()。现在数组唯一的优点是效率,但也是受限的。
16.2 数组是第一级对象
只读成员length是数组对象的一部分(这是唯一一个可以访问的字段或方法),表示此数组对象可以存储多少元素。“[]”语言是访问数组对象的唯一方式。
16.3 返回一个数组
补充:
(1)Object类的protected native Object clone()方法可以返回一个复制的对象。如果一个类想具有拷贝功能,需要该类实现Cloneable接口或Serializable接口。实现Cloneable接口:保证类及类内成员变量都实现Cloneable接口和clone()方法才能保证是深拷贝。实现Serializable接口:保证类及类内成员变量都实现Serializable接口,类的clone方法返回一个反序列化的对象。
https://blog.csdn.net/name_sakura/article/details/129251502
(2)native关键字会告诉JVM,这个方法是用C/C++实现的。Java可以通过JNI 和JNA技术与其它语言交互(JNA是对JNI的封装)。
https://blog.csdn.net/u014132659/article/details/56489375
16.4 多维数组
public class B extends A {
public static void main(String[] args) throws Exception {
int[][] ints = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
System.out.println(Arrays.deepToString(ints));
int[][] ints1 = new int[3][6];
System.out.println(Arrays.deepToString(ints1));
int[][] ints2 = new int[2][]; // 粗糙数组:数组的每个向量可以具有任意长度
ints2[0]= new int[4];
ints2[1]= new int[8];
System.out.println(Arrays.deepToString(ints2));
}
}
16.6 创建测试数据
16.6.1 Arrays.fill()
填充数组(只能用于一维数组)。复制同一对象的引用来填充。
public class B extends A {
public static void main(String[] args) throws Exception {
String[] s1 = new String[5];
Arrays.fill(s1, "ab");
System.out.println(Arrays.toString(s1));
}
}
16.6.2 数据生成器
16.7 Arrays实用功能
- equals,deepEquals
- fill
- sort
- binarySearch:二分查找
- toString
- hashCode:生成数组的散列码
- asList
- copyOf
16.7.3 数组元素的比较
Java有两种方式来提供比较功能:
(1)实现Comparable接口
public class B implements Comparable<B> {
int id;
public B(int id) {
this.id = id;
}
public int compareTo(B o) {
return (id < o.id ? -1 : (id == o.id ? 0 : 1) );
}
public static void main(String[] args) {
B b = new B(10);
int i = b.compareTo(new B(10));
System.out.println(i);
}
}
使用sort方法排序(参数类型需要实现Comparable接口)
public class B implements Comparable<B> {
int id;
public B(int id) {
this.id = id;
}
public int compareTo(B o) {
return (id < o.id ? -1 : (id == o.id ? 0 : 1) );
}
public String toString() {
return "" + id;
}
public static void main(String[] args) {
B[] bs = new B[]{new B(5), new B(1), new B(3), new B(2)};
Arrays.sort(bs); // 排序
System.out.println(Arrays.toString(bs));
}
}
(2)创建一个实现了Comparator接口的单独的类
当一个类已经实现了Comparable接口,但是不是我们想要的,就可以使用一个实现了Comparator接口的单独的类。
public class C implements Comparator<B> {
public int compare(B o1, B o2) {
return (o1.id < o2.id ? -1 : (o1.id == o2.id ? 0 : 1) );
}
public static void main(String[] args) {
B[] bs = new B[]{new B(5), new B(1), new B(3), new B(2)};
Arrays.sort(bs, new C()); // 使用Comparator
System.out.println(Arrays.toString(bs));
}
}
16.7.4 数组排序
使用内置的排序方法,就可以对任意的基本类型数组和对象数组(实现了Comparable或具有相关联的Comparator)进行排序。
public class C {
public static void main(String[] args) {
Integer[] ints = new Integer[]{40, 3, 1, 99};
Arrays.sort(ints, Collections.reverseOrder());
System.out.println(Arrays.toString(ints));
String[] ints2 = new String[]{"b", "a", "D", "B"};
Arrays.sort(ints2, String.CASE_INSENSITIVE_ORDER);
System.out.println(Arrays.toString(ints2));
}
}
Java标准库中针对基本类型使用快速排序,针对对象使用稳定归并排序。
16.7.5 在已排序的数组中查找
对已排序的数组使用Arrays.binarySearch()二分查找。如果找到目标,返回值大于等于0,否则,返回负值,负值的计算方式是:-(插入点)- 1
public class C {
public static void main(String[] args) {
Integer[] ints = new Integer[]{40, 3, 1, 99};
Arrays.sort(ints);
System.out.println(Arrays.toString(ints));
System.out.println(Arrays.binarySearch(ints, 1));
System.out.println(Arrays.binarySearch(ints, 3));
System.out.println(Arrays.binarySearch(ints, 40));
System.out.println(Arrays.binarySearch(ints, 99));
}
}
如果使用了Comparator对某个对象数组排序,在使用binarySearch时必须提供同样的Comparable(使用binarySearch的重载版)。
public class C implements Comparator<B> {
public int compare(B o1, B o2) {
return (o1.id < o2.id ? -1 : (o1.id == o2.id ? 0 : 1) );
}
public static void main(String[] args) {
B[] bs = new B[]{new B(5), new B(1), new B(3), new B(2)};
Arrays.sort(bs, new C()); // 使用Comparator
System.out.println(Arrays.toString(bs));
int i = Arrays.binarySearch(bs, new B(3), new C());
System.out.println(i);
}
}