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 }