今天 遇到了一个bug,抛出的异常大致是下面这样的。
Exception in thread “main” java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at java.util.AbstractCollection.retainAll(AbstractCollection.java:410)
例子:
public class test {
public static final Map<String, List<Integer>> MAP = new HashMap<String, List<Integer>>() {
{
put("122", Arrays.asList(3,4));
}
};
public static void main(String[] args) {
List<Integer> list = MAP.get("122");
Set<Integer> list1 = new HashSet<>();
list1.addAll(Arrays.asList(1, 2, 5, 6));
list.retainAll(list1);
System.out.println(MAP);
System.out.println(list);
System.out.println(list1);
}
}
表面上看是没有什么问题的,我们在将数组转成List的时候也经常会这么做,但是执行这样的代码的时候还是报错了,这就很奇怪。
我们看一下上面的报错信息得知是

在AbstractList.java:161位置报的错,我们找到对应的位置

这里表示List接口的remove、add等方法如果AbstractList类实现总会抛出此异常,即
不重写这个remove、add等方法的话就会抛出上面的异常。
问题其实是出在这一行
List<String> list = Arrays.asList(strings);
Arrays.asList(strings);方法返回的List对象不是我们常见的ArrayList,而是Arrays的一个内部类

此内部内刚好继承AbstractList
让我们看一下这个内部类都有哪些方法

其中并没有重写remove、add等方法,所以在调用remove、add等方法的时候会执行父类的remove、add等方法(也就是上面我们截图的方法),这样报错的原因就找到了。
找到原因后,问题就好解决了,我们把返回的对象处理一下 转成我们熟悉的List实现类就可以了,
方法一:
List<String> list = new ArrayList<>(Arrays.asList(strings));
方法二:
List<String> list = new ArrayList<>();
list.addAll(Arrays.asList(strings));