• java集合相关问题


    1.Map/Set 的 key 为自定义对象时,必须重写 hashCode 和 equals;

    2.ArrayList 的 subList 结果不可强转成 ArrayList,否则会抛出 ClassCastException 异常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList ; 

    说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上;

    在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、 删除均产生 ConcurrentModificationException 异常;

    3.使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全 一样的数组,大小就是 list.size()。 

    直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它类型数组将出现 ClassCastException 错误;

    4.使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常;

    原因:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组;下面的代码为Arrays内部类,其中没有实现list接口的相关集合操作方法:

     1  private static class ArrayList<E> extends AbstractList<E>
     2         implements RandomAccess, java.io.Serializable
     3     {
     4         private static final long serialVersionUID = -2764017481108945198L;
     5         private final E[] a;
     6 
     7         ArrayList(E[] array) {
     8             if (array==null)
     9                 throw new NullPointerException();
    10             a = array;
    11         }
    12 
    13         public int size() {
    14             return a.length;
    15         }
    16 
    17         public Object[] toArray() {
    18             return a.clone();
    19         }
    20 
    21         public <T> T[] toArray(T[] a) {
    22             int size = size();
    23             if (a.length < size)
    24                 return Arrays.copyOf(this.a, size,
    25                                      (Class<? extends T[]>) a.getClass());
    26             System.arraycopy(this.a, 0, a, 0, size);
    27             if (a.length > size)
    28                 a[size] = null;
    29             return a;
    30         }
    31 
    32         public E get(int index) {
    33             return a[index];
    34         }
    35 
    36         public E set(int index, E element) {
    37             E oldValue = a[index];
    38             a[index] = element;
    39             return oldValue;
    40         }
    41 
    42         public int indexOf(Object o) {
    43             if (o==null) {
    44                 for (int i=0; i<a.length; i++)
    45                     if (a[i]==null)
    46                         return i;
    47             } else {
    48                 for (int i=0; i<a.length; i++)
    49                     if (o.equals(a[i]))
    50                         return i;
    51             }
    52             return -1;
    53         }
    54 
    55         public boolean contains(Object o) {
    56             return indexOf(o) != -1;
    57         }
    58     }
    View Code

    5.不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁;

    这是因为在foreach循环里如果使用 remove/add 操作会改变集合大小从而导致循环报错;

    6.使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。 

    说明:keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出 key
    所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更
    高。如果是 JDK8,使用 Map.foreach 方法。

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

  • 相关阅读:
    Spring4+SpringMVC+MyBatis登录注册详细
    Spring MVC登录注册以及转换json数据
    MyBatis+mysql查询和添加数据
    html5中的选择器
    倒影(转)
    bi包
    函数作用域
    节点开始
    window.onload中失效的问题
    Node.js简介
  • 原文地址:https://www.cnblogs.com/CLAYJJ/p/6552737.html
Copyright © 2020-2023  润新知