首页 > 代码库 > 集合类操作需要注意的地方

集合类操作需要注意的地方

集合类操作需要注意的地方

1 概述

最近阿里巴巴在网上发布了《阿里巴巴Java开发手册》,自己看了看,有一些还是容易忽略。所以我把它里面集合操作规范以及自己觉得容易忽略的写了下来,免得自己忘了。

2 注意

2.1 关于hashCode与equals的处理,规则如下:

  1. 只要重写的equals,就必须重写hashCode。
  2. Set存放的是不重复的对象,HashSet与LinkedHashSet是依据hashCode与equals进行判断,所以使用HashSet与LinkedHashSet存放对象必须重写这两个方法。
  3. Map中的key也是不能重复的,所以同上处理。
  4. List中remove、contains也是根据equals进行比较的,所以使用List存放对象时也要重写equals方法。
  5. 最好使用工具类Objects的方法,避免判断是否为null对象。如Objects.equals(Object o1, Object o2)。
  6. @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if(obj instanceof People){
            People people = (People) obj;
            return Objects.equals(people.getHeight(),height);
        }
        return false;
    }

2.2 List接口的subList()方法

  1. ArrayList的subList结果不可强转成ArrayList。
  2. LinkedList的subList结果也不可以强制转换成LinkedList;
  3. subList 返回的List,是原来List的一个视图,对于SubList子列表的所有操作最终会反映到原列表上。
  4. 在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增
    加、删除均产生 ConcurrentModificationException 异常。

2.3 使用集合转数组,必须使用 T[] toArray(T[] array)方法

  1. 入参分配的数组空间不够大时,toArray 方法内部将重新分配内存空间,并返回新数组地址。
  2. 如果数组元素大于实际所需,不足的元素将被置为null。
  3. 因此最好将方法入参数组大小定义与集合元素。
  4. 该方法返回的是数组是新的内存空间,所以对List以及Array的操作都不会影响彼此。
  5. 1 List<String> list = new ArrayList<>(2);
    2 list.add("hello");
    3 list.add("world");
    4 String[] array = new String[list.size()];
    5 array = list.toArray(array);

2.4 数组转集合使用Arrays.asList()方法

  1. 该方法返回的集合实际上还是使用原来数组的内存空间,所以对List以及Array的操作都会影响彼此。
  2. 在使用List中的add/remove/clear方法时,会发生UnsupportedOperationException 异常。

2.5在 JDK7 版本以上, Comparator 要满足自反性,传递性,对称性。
说明:
1) 自反性: x, y 的比较结果和 y, x 的比较结果相反。
2) 传递性: x>y,y>z,则 x>z。
3) 对称性: x=y,则 x,z 比较结果和 y, z 比较结果相同。

1 class PeopleComparator implements Comparator<People>{
2     @Override
3     public int compare(People o1, People o2) {
4         return o1.getAge() > o2.getAge() ? 1 :
5                 (o1.getAge() == o2.getAge() ? 0 : -1);
6     }
7 }

2.6在使用集合,如果有指定容量的构造方法,则最好指定容量。避免扩容带来的资源消耗

2.7注意 Map 类集合 K/V 能不能存储 null 值的情况

集合类KeyValueSuper说明
Hashtable 不允许为 null 不允许为 null AbstractMap AbstractMap
TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全
HashMap 允许一个为 null 允许为 null AbstractMap 线程不安全
ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 分段锁技术

反例: 由于HashMap的干扰,很多人认为ConcurrentHashMap是可以置入null值,注意存储null 值时会抛出 NPE 异常。

2.8合理利用好集合的有序性(sort)和稳定性(order),避免集合的无序性(unsort)和不稳定性(unorder)带来的负面影响。
说明: 稳定性指集合每次遍历的元素次序是一定的。有序性是指遍历的结果是按某种比较规则依次排列的。如: ArrayList 是 order/unsort; HashMap 是 unorder/unsort; TreeSet 是order/sort。

2.9利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的contains 方法进行遍历、对比、 去重操作。

集合类操作需要注意的地方