集合中存放的依然是对象的引用,而不是对象本身
ArrayList:
1) ArrayList底层使用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组
2) 如果生成的数组超过10个,那么ArrayList底层会生成一个新的数组,长度为原数组的1.5倍+1,然后将原数组的元素复制到新数组之中,并且后续增加的内容都会放到新数组之中,当新数组无法容纳增加的元素时,重复该过程
3) 对于ArrayList元素的删除操作,需要将被删除元素的后续元素向前移动,代价比较高
4) 集合当中只能放置对象的引用,不能放置原生数据类型,当我们需要使用原生数据的包装类才能加入到集合当中
5) 集合当中放置的都是Object类型,因此取出来也是Object类型,必须强制转换
如果数据量很大,那么造成数组重新分配的次数会增加,但对于一般的数据量下,
1千需要分配 11次
1万一级需要分配17次
10万 需要分配23次
100万需要分配28次
所以,大家根据实际情况,大致分配一个初始化的容量还是有必要的。但是如果你初始容量太大,而数据增长很慢,那么就在浪费内存了。
System类中的一个JNI方式实现类.(JNI , Java Native Interface 故名思意,就是java 语言调其它语言的一个接口)
这个JNI的底层在不同的平台上不一样.打个比方windows 其实java的JNI就是调了dll . Unix 其实就是调了.so 共享库. 做过C++的一定明白.这个暂且放一下,让我们来关注一下arrayCopy 如何复制数组元素的. 如果有人对java 的JNI接口有兴趣朋友,不防去Sun网站下它的源码.嘎嘎. C代码还是有点深度的.SCSL 源码就能看到. 地址,
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter
(说明:要注册一个SUN的账号.才可以下载.)
LinkedList:
1) LinkedList底层使用双向链表实现
2) LinkedList的无参结构方法将第一个链表的下一个元素指向自己的上一个元素等于自己,增加元素的时候使用生成一个内部类对象,存放数据<E>,该元素的上一个对象,与下一个对象
将上一个元素的下元素指向自己,将下一个元素的上一个元素指向自己
3) 查找数据需要从第一个一直往第N个找
总结
a) ArrayList底层使用数组实现,LinkedList底层使用双向链表实现
b) 当执行插入或者删除操作时,采用Linked比较好
c) 当执行搜索操作时,采用ArrayList比较好
d) 当向一个ArrayList添加一个对象时,实际上就是将该对象的引用地址放置到了ArrayList底层所维护的数组当中,当向LinkedList中添加一个对象时,实际上LinkedList内部会生成一个Entry对象,该Entry对象的结构为:
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;// 新元素的内容
this.next = next; // 新元素的下一个元素为上一个元素
this.previous = previous;// 新元素的下一个元素为上一个元素
}
}
其中的Object类型的元素Element就是我们向LinkedList中所添加的元素,然后Entry又构造好了向前向后的引用previous、next最后将这个对象加入到链表当中,换句话说LinkedList中所维护的是一个个的Entry对象。
HashSet:
1)当使用HashSet时,hashCode()方法就会被调用,判断已经存储在集合中的对象的hashcode值是否与增加对象的hashcode是否一致
不一致:直接添加
一致:再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则进加进去