数组效率比集合高

数组效率比集合(List、Set、Map)高的原因:

  • 基本类型在栈内存中进行操作,对象则是在堆内存中操作,栈内存的特点是速度快,容量小;堆内存是速度慢,容量大
  • 集合中的基本类型的包装类在进行运算时,涉及到拆箱、装箱操作,有幸能损耗

因此,在性能要求严苛的系统上,可以使用数组来代替集合

数组是浅拷贝

  • Arrays.copyOf():通过该方法产生的数组是一个浅拷贝,即基本类型拷贝值,引用类型拷贝地址
  • 数组.clone():数组的clone()方法也是一个浅拷贝,集合的clone()方法也是浅拷贝 ```java class Box { int count;

    public Box(int count) {

    1. 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);

  1. <a name="8NMzz"></a>
  2. #### Arrays.asList 方法使用中的俩坑
  3. 1、**原始类型数组不能作为 asList 的输入参数**,否则会引起程序逻辑混乱
  4. Arrays.asList 源码:
  5. ```java
  6. public static <T> List<T> asList(T... a){
  7. return new ArrayList<T>(a);
  8. }

asList 方法输入的是一个泛型变长参数,而基本类型不能被泛型化,换句话说,8 个基本类型不能作为泛型参数,在 java 中,数组是一个对象,可以被泛型化,因此注意以下的区别:

  1. int[] data = {1, 2, 3, 4, 5};
  2. // 泛型化的是数组
  3. List<int[]> ints = Arrays.asList(data);
  4. Integer[] data1 = {1, 2, 3, 4, 5};
  5. // 泛型化的是Integer包装类
  6. 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:该类支持随机存取

列表相等只关注数据

  1. List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
  2. List<Integer> list2 = new ArrayList<Integer>(){{
  3. add(1);
  4. add(2);
  5. add(3);
  6. add(4);
  7. }};
  8. Vector<Integer> list3 = new Vector<Integer>(){{
  9. add(1);
  10. add(2);
  11. add(3);
  12. add(4);
  13. }};
  14. list1.equals(list2) == true;
  15. list2.equals(list3) == true;

为啥上述三个对象相等,原因是三者都是 List,实现了 List 接口,继承了 AbstractList 抽象类,而 equals 方法是在 AbstractList 中定义,其实现为比较两个 List 中元素是否相同且元素总量是否一致,只要元素数量相同且各元素向等,这两个列表就视为相等,即 equals 方法返回 true

Set、Map与List一样,equals都只关注集合中的元素是否相同

子列表只是原列表的一个视图

List.subList() 产生的列表只是一个视图,所有的修改动作直接作用于原列表,推荐使用 subList 处理局部列表

  1. List<Integer> list = new ArrayList<>(10);
  2. for (int i = 0; i < 10; i++) {
  3. list.add(i);
  4. }
  5. // 获取子列表
  6. List<Integer> subList = list.subList(1, 3);
  7. subList.add(0, 12);
  8. 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() ))也可以实现倒序排列

indexOf