Java踩坑之List的removeAll方法
最近写个功能,需要用到差集,然后就想到了java List 中有一个removeAll方法,正好可以实现差集功能,可以直接调用。
我们知道,apache 的common-collections 包下面得CollectionUtils.subtract()方法也可以对List作差集,为了比较两种方式差集的结果, 见Java 中 CollectionUtils.subtract() 和 List.removeAll() 方法求差集的区别 ,随手写了个测试方法,代码如下:
代码:
1 public class TestArray {
2
3 private void test1() {
4 List<Integer> a = Arrays.asList(1, 1, 2, 2, 3, 3, 4);
5 List<Integer> b = Arrays.asList(1, 2, 3);
6
7 a.removeAll(b);
8 System.out.println(a);
9 }
10
11 public static void main(String[] args) {
12 new TestArray().test1();
13 }
14 }
编译运行,结果如下:

给我整蒙了,然后,我写了另外一段代码,如下
1 public class TestArray {
2
3 private void test2() {
4 List<Integer> c = new ArrayList<>();
5 c.add(1);
6 c.add(1);
7 c.add(2);
8 c.add(2);
9 c.add(3);
10 c.add(3);
11 c.add(4);
12
13 List<Integer> d = new ArrayList<>();
14 d.add(1);
15 d.add(2);
16 d.add(3);
17
18 c.removeAll(d);
19 System.out.println(c);
20
21 }
22
23 public static void main(String[] args) {
24 new TestArray().test2();
25 }
26 }
莫名其妙的是,这次我又把结果输出来了:
>>> [4]
我比较了一下两段代码,发现问题出在List的创建方法上。
点击跟踪代码,可以发现,对于Arrays.asList(),返回的List是自己内部实现的ArrayList 而不是util下的ArrayList对象,它是一个不可变对象,因此调用removeAll等方法回出错
1 public static <T> List<T> asList(T... a) {
2 return new ArrayList<>(a);
3 }
4
5 /**
6 * @serial include
7 */
8 private static class ArrayList<E> extends AbstractList<E>
9 implements RandomAccess, java.io.Serializable
10 {
11 private static final long serialVersionUID = -2764017481108945198L;
12 private final E[] a;
13
14 ArrayList(E[] array) {
15 a = Objects.requireNonNull(array);
16 }
17 ......
18 }

浙公网安备 33010602011771号