数组效率比集合高
数组效率比集合(List、Set、Map)高的原因:
- 基本类型在栈内存中进行操作,对象则是在堆内存中操作,栈内存的特点是速度快,容量小;堆内存是速度慢,容量大
- 集合中的基本类型的包装类在进行运算时,涉及到拆箱、装箱操作,有幸能损耗
因此,在性能要求严苛的系统上,可以使用数组来代替集合
数组是浅拷贝
- Arrays.copyOf():通过该方法产生的数组是一个浅拷贝,即基本类型拷贝值,引用类型拷贝地址
数组.clone():数组的clone()方法也是一个浅拷贝,集合的clone()方法也是浅拷贝 ```java class Box { int count;
public Box(int count) {
this.count = count;
} }
// 数组的浅拷贝 Box[] boxes = new Box[3]; // 初始化 for (int i = 0; i < 3; i++) { boxes[i] = new Box(i); }
// 进行拷贝 Box[] copy = Arrays.copyOf(boxes, boxes.length); // 修改第一个 boxes[0].count = 12;
Box[] clone = copy.clone();
for (Box box : boxes) { // 12 1 2 System.out.println(box.count); }
// [top.songfang.basic.ArrayTest$Box@3d82c5f3, top.songfang.basic.ArrayTest$Box@2b05039f, top.songfang.basic.ArrayTest$Box@61e717c2] System.out.println(Arrays.toString(copy)); // [top.songfang.basic.ArrayTest$Box@3d82c5f3, top.songfang.basic.ArrayTest$Box@2b05039f, top.songfang.basic.ArrayTest$Box@61e717c2] System.out.println(Arrays.toString(clone)); // false System.out.println(copy == clone);
<a name="8NMzz"></a>
#### Arrays.asList 方法使用中的俩坑
1、**原始类型数组不能作为 asList 的输入参数**,否则会引起程序逻辑混乱
Arrays.asList 源码:
```java
public static <T> List<T> asList(T... a){
return new ArrayList<T>(a);
}
asList 方法输入的是一个泛型变长参数,而基本类型不能被泛型化,换句话说,8 个基本类型不能作为泛型参数,在 java 中,数组是一个对象,可以被泛型化,因此注意以下的区别:
int[] data = {1, 2, 3, 4, 5};
// 泛型化的是数组
List<int[]> ints = Arrays.asList(data);
Integer[] data1 = {1, 2, 3, 4, 5};
// 泛型化的是Integer包装类
List<Integer> integers = Arrays.asList(data1);
2、Arrays.asList() 方法产生的 List 对象不可更改,返回的为 ArrayList ,然而这个 ArrayList 不是 java.util.ArrayList ,而是 Arrays 内置的一个工具类,该类实现了 List 接口,然而只对 size()、toArray()、get()、set()、contains() 这五个方法作了实现,不支持添加、删除等操作,因此,谨慎使用 Arrays.asList()
特殊的标识类接口
- Clonable:允许被拷贝
- Serializable:支持序列化
- RandomAccess:该类支持随机存取
列表相等只关注数据
List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
List<Integer> list2 = new ArrayList<Integer>(){{
add(1);
add(2);
add(3);
add(4);
}};
Vector<Integer> list3 = new Vector<Integer>(){{
add(1);
add(2);
add(3);
add(4);
}};
list1.equals(list2) == true;
list2.equals(list3) == true;
为啥上述三个对象相等,原因是三者都是 List,实现了 List 接口,继承了 AbstractList 抽象类,而 equals 方法是在 AbstractList 中定义,其实现为比较两个 List 中元素是否相同且元素总量是否一致,只要元素数量相同且各元素向等,这两个列表就视为相等,即 equals 方法返回 true
Set、Map与List一样,equals都只关注集合中的元素是否相同
子列表只是原列表的一个视图
List.subList() 产生的列表只是一个视图,所有的修改动作直接作用于原列表,推荐使用 subList 处理局部列表
List<Integer> list = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
list.add(i);
}
// 获取子列表
List<Integer> subList = list.subList(1, 3);
subList.add(0, 12);
list = [0, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9];
使用 Comparator 将进行排序
在 java 中,想给数据排序,有两种实现方式:
- 一种是实现Comparable接口
- 一种是实现Comparator接口
Comparable接口可以作为实现类的默认排序法,Comparator接口则是一个类的扩展排序工具
- Collections.sort(List
list , Comparator<? super T> c):可以接受一个 Comparator 实现类进行排序 - Collections. reverse(List<?>list):方法实现倒序排列
- 通过Collections.sort(list , Collections.reverseOrder( newPositionComparator() ))也可以实现倒序排列