java.lang.UnsupportedOperationException list集合開發中的問題

 

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章