从Java的list<String>中删除一个值会抛出java.lang.UnsupportedOperationException异常。

8

我想从我的列表中删除特定的元素。我不想在迭代列表时这样做。我想指定要删除的值。在javadoc中,我找到了函数List.remove(Object 0)。这是我的代码:

         String str="1,2,3,4,5,6,7,8,9,10";
         String[] stra=str.split(",");
         List<String> a=Arrays.asList(stra);
         a.remove("2");
         a.remove("3");

但是我得到了一个异常:java.lang.UnsupportedOperationException
2个回答

26
问题在于Arrays.asList()返回一个不支持插入/删除的列表(它只是对stra视图)。
要解决这个问题,更改:
List<String> a = Arrays.asList(stra);

目标:

List<String> a = new ArrayList<String>(Arrays.asList(stra));

这将创建列表的一个副本,允许您对其进行修改。


它可以工作。谢谢。我的方法有什么问题?List<String> a=Arrays.asList(stra); 异常没有在这一行抛出。 - Ashwin
@Ashwin:那行代码没问题。但是Arrays.asList()生成的列表是只读的,所以你不能修改它。你必须先复制一份。 - NPE
好的,使用我的方法,列表是直接访问string[]值而不制作自己的副本吗?因此,如果允许进行任何更改,它们也会影响String[],对吗? - Ashwin

3

1
一个字符串也是不可变的。但是当你修改一个字符串时,它会被分配一个新的内存位置,并在内部创建一个新的字符串。因此,实际上你可以修改一个不可变的字符串。所以我认为这里的原因不是返回的列表是不可变的。我认为问题在于当你执行Arrays.asList()时,它只是引用了string[](没有复制string[]并创建一个列表)。 - Ashwin
如果您查看Arrays类中的内部类调用AraayList,您会意识到它无法被修改。简单地说,它使用一个私有的final E[] a; 这就是为什么您不能修改返回的列表。在字符串的情况下,一旦创建了字符串,就无法修改它。但是,在字符串类API中,它是以一种处理内部修改的方式开发的,通过创建一个新对象来处理。 - Eshan Sudharaka
所以你的意思是它创建了一个 string[] 的副本,但将其声明为 final。你是说它不引用 string[] 并存储自己的副本(但作为 final)? - Ashwin
1
@SafeVarargs public static <T> List<T> asList(T... a) { return new ArrayList<>(a); }private final E[] a; ArrayList(E[] array) { if (array==null) throw new NullPointerException(); a = array; }我从API中复制了这段代码。 - Eshan Sudharaka
好的,所以它确实创建了一个新的ArrayList对象。但是将其分配给了final e[]。我仍然不明白为什么在Java中声明为final。感谢提供信息 :) - Ashwin
在您的情况下,Array stra 和 String array list 引用同一对象。如果您可以从列表中删除元素会发生什么?它也会反映在数组中(因为它引用同一对象)。因此,最终 stra 数组会缺少一些元素,即使不知道这可能会导致一些意外行为。 - Eshan Sudharaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接