1.集合
集合是个容器,它主要用来存放对象。在集合中真正存放的是对象的内存地址(引用)。
集合的顶层接口:
Collection接口:它中定义了所有集合的共性的操作规则。其下有2个重要的子接口Set和List接口。
增加:add(Object obj) addAll( Collection coll )
删除:remove( Object obj ) clear() 清空 removeAll( Collection coll ) 删除集合中的交集
retainAll( Collection coll ) 保留2个集合中的交集
判断:isEmpty() 判断集合中是否有元素 contains(Object obj ) 判断是否包含指定的元素
containsAll( Collection coll )
获取集合中元素的个数:size()
迭代器:它主要是定义了所有集合共性的遍历方式 Iterator
而每个集合都有自己的迭代方式,而在Collection接口中定义了共性的方法iterator可以获取到当前某个集合自己的迭代器对象。
迭代器中: hasNext 判断有没有下一个元素
next 取出下一个元素
remove 删除当前判断后的那个元素
1.1 集合与数组区别
1)从长度来讲:
数组:需要固定长度。
集合:长度可以改变,可以根据保存的数据进行扩容。
2)从存储内容上:
数组:可以存储基本类型数据,还可以存储引用类型的数据(比如:String和上述演示的Student类)。
集合:只能存储引用类型的数据,也就是说集合只能存储类的对象。
3)从存储类型上:
数组:只能存储相同类型的数据。
集合:可以存储不同类型的数据,集合中可以存储任意类型的引用数据类型。
2、List接口:
List接口下的所有集合中存放的元素都可以重复,同时这些集合中的元素都有下标。因此我们可以像操作数组一样操作集合。
List接口中定义了自己的特有方法:都是围绕下标而设计的方法。
add( int index , Object obj )
remove( int index )
get( int index )
set( int index , Object obj )
ArrayList类(集合):它是List接口的一个直接实现类,因此ArrayList集合拥有List接口的所有特性。
ArrayList集合的特点:
1、它的底层使用的可变数组;
如果初始容量不够会立刻重新创建数组,将原来的数据复制存放到新的数组前面空间中,多余的数据继续向数组其他空间进行存储。
2、它有下标,可以按照数组的方式操作ArrayList集合;
3、可以保证数据的存取顺序(第一个元素添加到集合中,那么取出也是第一个取出),同时还可以保存重复元素,也可以存储null元素;
4、ArrayList集合它增加和删除效率比较低,而查询(遍历)速度较快;
解释:为什么ArrayList集合增删效率低,而查询速度快?
因为我们向集合中添加元素的时候,有时会将元素添加到集合中的最前面,或者有可能删除最前面的数据,这样就导致其他数据向后移动或者删除时向前移动,所以效率会低。
对于查询ArrayList集合,由于ArrayList集合是数组结构,而数组结构是排列有序的,并且下标是有序增加的,当查询ArrayList集合的时候可以按照排列顺序去查询,或者直接可以通过某个下标去查询,这样就会导致查询速度相对来说会快很多。
LinkedList集合:它也是List接口的实现类,它的底层使用的链接列表(链表)数据结构。
总结:
1)数组结构查询快,但是增删慢;
2)链表结构查询慢,但是增删快;
上述两种数据结构快慢只是相对来说。
LinkedList集合特点:
1、它的底层使用的链表结构;
2、有头有尾,其中的方法都是围绕头和尾设计的;
3、LinkedList集合可以根据头尾进行各种操作,但它的增删效率高,查询效率低;
LinkedList集合增删效率高是因为底层是链表结构,如果增加或者删除只需要在增加或者删除节点的位置上记住新的节点的地址即可,而其他节点不需要移动,所以速度会快。
而查询遍历由于链表结构的特点,查询只能从头一直遍历到链表的结尾,所以速度会慢。
4、LinkedList集合底层也是线程不安全。效率高;
也可以存储null元素;
Vector集合是JDK1.0的时候出现的集合,它在jdk1.2的时候被收编到List接口的下面。而这个集合被JDK1.2中的ArrayList集合代替。
通过查阅API得知,Vector集合从jdk1.0版本就已经存在了,而迭代器Iterator是从jdk1.2版本开始才引入的,那么在jdk1.2版本之前是怎么对Vector集合进行迭代和遍历取出集合中的数据呢?
解释说明:
1)在1.2版本之前我们借助于另一个接口Enumeration来实现迭代的;
2)使用接口Enumeration对集合进行迭代,可以先使用Vector集合的对象调用Vector集合中的elements()函数来获得接口Enumeration的对象;
3)然后使用接口Enumeration的对象调用hasMoreElements()判断集合中是否还有元素,有返回true;
4)然后使用接口Enumeration的对象调用nextElement()函数获取集合中的元素;
Vector集合它就是ArrayList集合,可以使用Enumeration迭代Vector集合,但是由于Enumeration迭代器中的方法的名字太长,被Iterator代替。后期如果需要迭代器Vector应该优先考虑使用Iterator迭代。
Vector集合的特点:
1)Vector是jdk1.0出现的集合,它的增删,查询效率都比较低;
2)由于Vector底层是线程安全的。ArrayList 的底层是不安全的,因此ArrayList各方面的效率都比Vector高。
3)对于Vector类现在开发中已经几乎不再使用。
List下的子类总结
Collection集合(接口)
|----List集合(接口):可以存储重复元素、可以存储null、有角标、存取有序。
|----ArrayList集合(类):实现List接口。ArrayList集合中的特有方法是实现List
底层使用可变数组结构。
查询遍历的效率比较高、增删的效率比较低
属于线程不安全的集合类。执行效率比较高
|----LinkedList集合(类):实现List接口。
底层使用链表结构。(链表:有头有尾)
LinkedList集合中的特有方法都是围绕链表的头尾设计
查询遍历的效率比较慢、增删的效率比较高
属于线程不安全的集合类。执行效率比较高
|----Vector集合(类):实现List接口。线程安全的集合类。
底层使用可变数组结构。查询遍历效率、增删效率都比较低。
Vector类属于线程安全的集合类。效率比较慢。现在开发中已经不再使用。
问题:遇到对线程有需求的情况,应该使用哪个集合类?
还使用LinkedList、ArrayList(在后面学习过程中,可以解决LinkedList ArrayList线程不安全的问题)
1)解释:为什么ArrayList集合增删效率低,而查询速度快?
因为我们向集合中添加元素的时候,有时会将元素添加到集合中的最前面,或者有可能删除最前面的数据,这样就导致其他数据向后移动或者删除时向前移动,所以效率会低。
对于查询ArrayList集合,由于ArrayList集合是数组结构,而数组结构是排列有序的,并且下标是有序增加的,当查询ArrayList集合的时候可以按照排列顺序去查询,或者直接可以通过某个下标去查询,这样就会导致查询速度相对来说会快很多。
2)解释:为什么LinkedList集合增删效率快,而查询速度慢?
LinkedList集合增删效率高是因为底层是链表结构,如果增加或者删除只需要在增加或者删除节点的位置上记住新的节点的地址即可,而其他节点不需要移动,所以速度会快。
而查询遍历由于链表结构的特点,查询只能从头一直遍历到链表的结尾,所以速度会慢。