在目中对List进行操作时报错java.lang.UnsupportedOperationException,后来发现操作的List是由数组转换而成的,通过看源码发现问题,并写测试程序如下。
public class arrayTest {
public static void main(String[] args) {
String[] str = {"1","2","4","5"};
List<String > list = Arrays.asList(str);
list.add("xzzz");
System.out.println(list.toString());
}
}
执行结果:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at com.cy.test.arrayTest.main(arrayTest.java:11)
Process finished with exit code 1
发生问题的原因如下:
调用Arrays.asList()生产的List的add、remove方法时报异常,这是由Arrays.asList() 返回的市Arrays的内部类ArrayList, 而不是java.util.ArrayList。Arrays的内部类ArrayList和java.util.ArrayList都是继承AbstractList,remove、add等方法AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。java.util.ArrayList重新了这些方法而Arrays的内部类ArrayList没有重新,所以会抛出异常。
通过 类图可以看到 类中没有add 等方法
查看源码:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
//返回ArrayList<>(a) 点击进去查看
return new ArrayList<>(a);
}
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
解决方法如下:
public class arrayTest {
public static void main(String[] args) {
String[] str = {"1","2","4","5"};
List<String > list = Arrays.asList(str);
//转换为arrayList
List<String > list2 = new ArrayList<>(list);
// 也可以简化为
List<String > list3 = new ArrayList<>(Arrays.asList(str));
list2.add("xzzz");
System.out.println(list2.toString());
}
}
除了不支持增删 改动数组元素会影响原数组
String[] str = {"2","4","5"};
List<String> list = Arrays.asList(str);
list.set(0,"aaa");
str[1] = "bbb";
System.out.println(Arrays.toString(str));
System.out.println(list);
结果:
[aaa, bbb, 5]
[aaa, bbb, 5]
查看源码:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
//返回ArrayList<>(a) 点击进去查看
return new ArrayList<>(a);
}
//这里调用使用了 数组 E[] array
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
修改:
String[] str = {"2","4","5"};
List<String> list = Arrays.asList(str);
//List<String> list2 = new ArrayList<String>(list);
List<String> list2 = new ArrayList<String>(Arrays.asList(str));
//转换为arrsylist数组后增删没有问题不会影响其他操作
list2.set(0,"aaa");
str[1] = "bbb";
System.out.println(Arrays.toString(str));
System.out.println(list2);
List<Integer> inte = new ArrayList<>();
inte.add(1);
inte.add(2);
inte.add(3);
inte.add(4);
//sublist 同理转换
List<Integer> subList = new ArrayList<>(inte.subList(0, 2));
inte.set(0, 666);
subList.set(1, 999);
System.out.println(inte);
System.out.println(subList);
String[] str = {"1","2","3"};
List<String> stringList = new ArrayList<>(Arrays.asList(str));
//使用增强for循环删除元素会报错
for (String s : stringList) {
if (s.equals("1")){
stringList.remove(s);
}
}
//使用迭代器删除元素
Iterator<String> iterator = stringList.iterator();
//遍历集合
while (iterator.hasNext()){
String st = iterator.next();
if (st.equals("1")){
stringList.remove(s);
}
}
//jdk1.8 特性
stringList.removeIf(s -> s.equals("1"));