Collections ArrayList(集合c)与HashSet(集合c)
在检查ArrayList API时,我注意到一些看起来很奇怪的东西 实际上,这里的ArrayList构造函数实现将集合作为参数传递:Collections ArrayList(集合c)与HashSet(集合c),collections,java,Collections,Java,在检查ArrayList API时,我注意到一些看起来很奇怪的东西 实际上,这里的ArrayList构造函数实现将集合作为参数传递: public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[]
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
公共阵列列表(集合
ArrayList one使用参数中集合提供的元素的副本(Arrays.copyOf),而HashSet one使用addAll()方法
否,array.copyOf
仅复制数组,而不复制此数组指向的对象。对象不会被克隆。也就是说,两个构造函数的行为相同-它们将包含对与原始集合相同的对象的引用。修改一个集合中的对象将修改另一个集合中的对象(因为它是同一个对象)
还请注意,Arrays.copyOf()
仅在某些情况下使用。ArrayList
和HashSet
都将仅复制引用,而不是这些引用所引用的实际对象
在Java中,非原语类型的变量是对对象的引用。如果您有一个这样的数组,那么数组。copyOf
只复制引用,而不是那些引用引用所引用的对象。集合将具有相同的引用。如果您有一个包含三个对象的列表,即a、B、C,并复制该列表,则新的副本将我也会引用那些相同的3个对象。这些构造函数都很浅,它们根本不接触原始对象
public static void main(String args[]) {
ArrayList l = new ArrayList();
Object a = new Object();
Object b = new Object();
Object c = new Object();
l.add(a);
l.add(b);
l.add(c);
ArrayList k = new ArrayList(l);
HashSet h = new HashSet(l);
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(l);
System.out.println(k);
System.out.println(h);
}
给出:
java.lang.Object@43256ea2
java.lang.Object@4e82701e
java.lang.Object@558ee9d6
[java.lang.Object@43256ea2, java.lang.Object@4e82701e, java.lang.Object@558ee9d6]
[java.lang.Object@43256ea2, java.lang.Object@4e82701e, java.lang.Object@558ee9d6]
[java.lang.Object@4e82701e, java.lang.Object@43256ea2, java.lang.Object@558ee9d6]
您会注意到所有集合都引用相同的对象。(哈希集的顺序不同。)+1复制的唯一目的是使向原始源数组添加条目不会同时影响您的ArrayList。@mellamokb:甚至不是这样,c.toArray()
保证返回新数组,即使在调用ArrayList
@Tomasz Nurkiewicz谢谢:)时也是如此,因此我现在可以理解HashSet不生成arrayCopy的原因=>在HashSet中,有哈希的概念,因此不必进入添加过程(即计算散列并为每个元素选择对应表索引),无需预先设想元素的位置。
java.lang.Object@43256ea2
java.lang.Object@4e82701e
java.lang.Object@558ee9d6
[java.lang.Object@43256ea2, java.lang.Object@4e82701e, java.lang.Object@558ee9d6]
[java.lang.Object@43256ea2, java.lang.Object@4e82701e, java.lang.Object@558ee9d6]
[java.lang.Object@4e82701e, java.lang.Object@43256ea2, java.lang.Object@558ee9d6]