组里来了一个实习生,一行代码引发了一个惨案
The following article is from 程序员修炼 Author 静幽水
第一时间收到文章更新
出品 | 程序员修炼(ID:cxyxl6)
int[] ruleIds = new int[roleList.size()];
for (int i = 0; i++; i<roleList.size() ) {
ruleIds[i] = roleList.get(i).getId;
}
List<Integer> ruleIdList = Arrays.asList(ruleIds);
if (ruleIdList.size() == 0){
ruleIdList.add(defaultId)
}
// Arrays类的源码
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
// Arrays类的内部类ArrayList的源码
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable {
private final E[] array;
ArrayList(E[] array) {
if (array == null) {
throw new NullPointerException();
}
this.array = array;
}
public E get(int index) {
return array[index];
}
public int size() {
return array.length;
}
// 不支持修改集合结构的方法
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
}
从ArrayList类的源码可以看出,它继承了AbstractList类并实现了RandomAccess接口,因此支持快速随机访问。但是在ArrayList类中,修改集合结构的方法都被重写为抛出UnsupportedOperationException异常,从而保证了对返回的List进行修改的操作是不可行的。
除了Arrays.asList()方法,还存在其他类似的坑,它们在处理集合时也需要注意。
Collections.nCopies()
Collections.nCopies()方法用于创建一个指定元素重复多次的List。这个List同样是固定大小的,不能进行修改操作。
List<String> list = Collections.nCopies(3, "apple");
list.add("banana"); // 抛出UnsupportedOperationException异常
原理和Arrays.asList()类似,Collections.nCopies()方法返回的是一个AbstractList的实例,不支持修改集合结构的操作。
Arrays.asList()的嵌套问题
Arrays.asList()方法还存在一个嵌套的问题。如果使用Arrays.asList()方法将一个二维数组转换为List,会得到一个List的嵌套结构,此时对内层的List进行修改同样会抛出UnsupportedOperationException异常。
String[][] array2D = { { "apple", "banana" }, { "orange", "grape" } };
List<List<String>> nestedList = Arrays.asList(array2D);
nestedList.get(0).add("kiwi"); // 抛出UnsupportedOperationException异常
原因是这个嵌套的List中的元素仍然是固定大小的List。
这种设计是为了提高效率和节省内存开销。在转换数组到集合时,能直接使用Arrays.asList()方法的时候,它是非常方便的。但是当需要对集合进行修改操作时,应该创建一个新的ArrayList对象,并使用addAll()方法将数组元素添加进去,以避免UnsupportedOperationException异常的发生。
代码示例:
String[] array = { "apple", "banana", "orange" };
List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.add("grape"); // 正常添加元素到集合中
或者如下:
List<String> Ids = new ArrayList<>(Arrays.asList(array));
Ids.add(id);
Collections.unmodifiableList()方法的不可修改特性
Collections.unmodifiableList()方法返回的是一个不可修改的List。它采用了装饰器模式,对原始List进行了封装,重写了修改集合结构的方法并抛出UnsupportedOperationException异常。
List<String> originalList = new ArrayList<>();
originalList.add("apple");
List<String> unmodifiableList = Collections.unmodifiableList(originalList);
unmodifiableList.add("banana"); // 抛出UnsupportedOperationException异常
总结: 在使用Arrays.asList()方法将数组转换为集合时,注意其局限性。返回的List是一个固定大小的List,不支持修改集合结构的方法。类似的坑还有Collections.nCopies()方法和Arrays.asList()的嵌套问题,它们同样需要注意不能对返回的集合进行修改操作。
面试官:try-catch 到底写在循环里面好,还是外面好?大部分人都会答错! 号称可替代Chrome的Arc浏览器发布 1.0 版本 学了两门编程语言后才知道的一些事 你有什么事是当程序员之后才懂的? 程序员神器VS Code新上架跨平台应用开发扩展——由微软打造