Collection是Java单列集合的统一接口契约,规定add、remove等方法但不实现;不能直接实例化,需用ArrayList等实现类多态创建;add返回boolean表示是否发生结构性改变,非简单成败判断。

Collection 接口不是具体类,而是 Java 单列集合的统一契约——它不存数据,只规定“能做什么”,比如 add、remove、contains、iterator 这些方法必须有,但怎么实现,由 ArrayList、HashSet、LinkedList 等子类自己决定。
为什么不能 new Collection()?
因为 Collection 是接口,没有构造方法,也不能直接实例化。你写 Collection 会编译报错:Error: cannot instantiate the type Collection。
- 正确做法是用多态:用它的实现类来创建对象,再向上转型为
Collection引用,例如Collectioncoll = new ArrayList() - 这样写的好处是后续代码只依赖接口,换实现类(比如改成
new LinkedList())时,add/remove等调用完全不用改 - 注意:虽然
Collection允许声明为泛型(如Collection),但它本身不约束元素是否可重复、是否有序——这些由子接口(List、Set)和具体实现类决定
add() 返回 boolean 到底在判断什么?
add(E e) 方法返回 true 表示集合因本次操作发生了结构性改变(比如真把元素加进去了);返回 false 并不一定是失败,而可能是“没变”——典型例子是往 Set 中添加已存在的元素,HashSet.add("a") 第二次调用就返回 false。
-
ArrayList.add()几乎总是返回true(除非容量溢出且无法扩容,但实际极少发生) -
Set系列的add()返回值才是关键判断依据:可用于去重逻辑或避免冗余处理 - 别把它当“成功/失败”二值开关用,要结合具体实现语义理解——比如
LinkedHashSet和TreeSet的add都遵守这一规则,但性能开销差异很大
toArray() 为什么有两个版本?
toArray() 返回 Object[],类型擦除后无法还原泛型信息;toArray(T[] a) 才能返回带具体类型的数组,比如 String[] arr = list.toArray(new String[0])。
立即学习“Java免费学习笔记(深入)”;
- 传
new String[0]比new String[list.size()]更推荐:JVM 可优化,且避免因预估不准导致额外复制 - 如果传入数组长度不够,JVM 自动新建一个同类型数组返回;如果够用,则复用原数组(可能被修改),所以别拿外面缓存的数组反复传入
- 用
toArray()(无参版)拿到Object[]后强转成String[]会抛ClassCastException——这是新手高频翻车点
真正容易被忽略的是:Collection 接口方法的行为边界全靠实现类自己守约。比如 removeAll 在不可修改集合(Collections.unmodifiableList)上调用,会直接抛 UnsupportedOperationException;而 contains 对 null 的支持与否,也取决于实现——ArrayList 允许,TreeSet 不允许。写通用工具方法时,别假设所有 Collection 子类都表现一致。









