使用List的removeIf()方法抛出UnsupportedOperationException的原因及解决
嘿,这个问题我碰到过好几次了,我来给你掰扯清楚!
先看看你写的代码:
public class T { public static void main(String[] args) { String[] arr = new String[] { "1", "2", "3" }; List<String> stringList = Arrays.asList(arr); stringList.removeIf((String string) -> string.equals("2")); } }
为啥会抛出UnsupportedOperationException?
问题出在Arrays.asList(arr)返回的List上——它不是我们平时常用的java.util.ArrayList,而是java.util.Arrays类里的一个静态内部类ArrayList。这个内部类只是对原始数组做了一个“包装”,让它能以List的形式被访问,但它本质还是依赖原始数组,不支持任何会改变List结构的操作(比如添加、删除元素,或者调整大小)。
当你调用removeIf()方法时,它会尝试删除符合条件的元素,这属于修改List结构的操作,而这个内部类并没有实现这些修改方法,所以就直接抛出了UnsupportedOperationException。
解决办法
有几种简单的方式可以解决这个问题:
1. 转换成真正的可修改ArrayList
把Arrays.asList()返回的包装类转换成java.util.ArrayList,这样就拥有了完整的List修改能力:
public class T { public static void main(String[] args) { String[] arr = new String[] { "1", "2", "3" }; // 把包装类转成真正的ArrayList List<String> stringList = new ArrayList<>(Arrays.asList(arr)); stringList.removeIf(string -> string.equals("2")); System.out.println(stringList); // 输出 [1, 3] } }
2. 使用Stream API过滤生成新List
如果你不想修改原List,而是想要一个过滤后的新List,可以用Stream来处理:
import java.util.stream.Collectors; public class T { public static void main(String[] args) { String[] arr = new String[] { "1", "2", "3" }; List<String> filteredList = Arrays.asList(arr) .stream() .filter(string -> !string.equals("2")) // 过滤掉等于"2"的元素 .collect(Collectors.toList()); System.out.println(filteredList); // 输出 [1, 3] } }
这种方式不会修改原数组和原包装List,而是生成一个全新的可修改List(默认是ArrayList)。
3. Java 9+ 可选方案(注意不可变限制)
如果你用的是Java 9及以上版本,也可以先把数组转成不可变List,再转成可修改的ArrayList:
public class T { public static void main(String[] args) { String[] arr = new String[] { "1", "2", "3" }; List<String> stringList = new ArrayList<>(List.of(arr)); stringList.removeIf(string -> string.equals("2")); System.out.println(stringList); // 输出 [1, 3] } }
不过要注意List.of()返回的也是不可变List,所以还是需要转成ArrayList才能进行修改操作。
内容的提问来源于stack exchange,提问作者Joker
相关产品推荐
相关产品推荐

