在目中對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"));