做什么事情都要先明确其大纲
一:为什么会出现集合框架
由来:早期是没有集合框架这一说的,因为当时有数组就可以了。但是随着Java的发展与市场的不断需
求,就出现了集合框架,比如数组时存储基本数据类型的,当然也可以存储自定义类型,但是其长度必
须是固定的,查询删除修改元素的时候,都必须通过角标。这就很不方便,为什么呢?因为你通过角操
作数据,那么你怎么记着每个具体元素对应的角标呢?比如一个数组中有{d,b,t,g},等过段时间后,
你怎么知道t在数组中的那个问题呢?
所以Java在早期就出现了原始的集合Vector,由于早期注重的是安全,所以其为线程安全的。但是随着
市场需求的不断增多,效率就成了社会的主流,这时Vector就不能满足需求,就需要有新的效率高的集
合来代替。这就出现了集合框架,根据面向对象的思想,不可能让一个集合具有所有的优点,因为这不
现实。 所以就出现了多个不同的集合,这些不同的集合都有各自的特点,但又有共同的方面,所以为
了让他们有归宿并且形成体系,就把他们共性的方面给抽取出来,形成他们的父类,让特征不同的集合
继承,这样就有了集合框架。
二:集合框架与数组的区别:
1:最大的区别集合框架存储的是引用数据类型,不能是基本数据类型
2:集合的长度是可变的,数组的是不可变的
三:集合框架的体系结构
Collection
List
Vector Set
ArrayList
LinkedList
HashSet
TreeSet
LinkedHashSet
四:看体系的方法:
要看一个体系,首先要看的就是他们的最底层,所以我们先看框架集合的祖宗Collection。。。。。。
1:Collection有什么特点
规律一:凡是祖宗一般其必为接口,遗憾的是Collection没有逃脱这个规律,它也是接口。那么接下来
我们就要看这个接口(对象)
其特点:
1:长度可变(说明是数组)
2:元素可以重复(所以有角标),因此第三点可以不说
3:元素有角标
有哪些行为呢?
一个类(对象)中无非要么是方法(功能),要么是属性,要么是二者都有。遗憾的是Collection只有
功能(方法),所以接下来看看它有
什么具体方法?
一个对象所具有的方法不过以下四类:增删改查
1:增: 所以我们先看Collection的增加的方法,试想如果是自己定义,参数是什么,返回值是什么?
如果是我定义的,肯定需要参数,没有返回值。这是我初次的想法,但是如果添加不成功怎么办?所以之
前的想法是错的,必须有返回值但是返回值是什么类型的好呢?试想,如果是int型的,添加成功返回1,
不成功返回0,这可以。但是有另一种更加好的返回类型,boolean型,成功返回true,不成功返回false,
这也可以。
但为什么比int型更好呢?
因为我们有时候不必写返回值true与false,比如 return
a>b;如果成功,自己就可以返回true但是如果返
回的是int型,就需如下
if(a>b) return
1;
else 0;
这样写不但代码繁琐而且格式不优美,所以其add方法如下
boolean
add(E e);//添加单个元素到集合中
boolean add(Collection<? extends
T> c)//把一个集合中的元素添加到另外一个集合中
2:删
删除集合中的元素:
以为Collection补充了数组的不足,删除元素通过对象,而不是角标返回值为boolean
boolean remove(Object o);
boolean revoveAll(Collection<?
extends T> c);//查找并移除集合中相同的元素
void clear();
3:查:
boolean contains(Object o)//元素是否包含在指定集合中
boolean contionsAll(Collection<? extends
T> c);//参数集合是否包含的指定集合中
boolean isEmpty();//集合是否为空
boolean retaionAll(Collection<?
extends T> c);//查找并保留相同的元素
4:取 如何的把集合中的元素全部的取出来,是非常重要的一个方面,但是Collection也为我们提供好了功能
其参数是什么呢?因为是取集合自身的元素,所以没有参数。
但是返回值类型是什么呢?
因为每个子类的特点不一样,所以他们存储的数据也是不一样的,所以导致他们的取出方式更是不一样,
所以返回的应该是怎么去元素的那个对象,即迭代器Iterator iterator()
5:其它功能
由于数组胡集合有很多的相识型,所以集合就产生一个将集合转为数据的方法返回值理应为Object型的数
组,不想要参数,因为涉及到的只是自己在转变,如何转只有自己知道,所以无参 Object[]
toArray();
但是总是返回Object型的数组总是不舒服的,因为有时候我们知道具体的返回值类型,所以方法如下
T[]
toArray(T[] a);
注意:
在参数中可以指定数组的长度也可以不指定,如果指定的数组大小小于集合中的元素个数,则会重新创建一
个默认的能装下集合元素的数组
如果指定的数组大了,则多余的用null填充,
所以最好的是指定一个与集合元素个数相同的数
总结:
这些都是所有集合都具有的共性内容,所以下面看他下面的子类的特有功能吧。。。。。。。。
--------------------------------------------------------------------------------------------------
注意:Collection集合的特点之一就是元素有下标,但是我们在其具体的方法上并没有看到太多使用下标的情
况。为什么呢?
因为它是集合框架的超级接口,它所有的是元素共有的方法。
因此,这些具体的方法都是在其子类里面,首先看一下他的第一个我们常用的子类
List集合:
1:List的由来:
list集合不幸的是也是一个接口,因为Collection的体系过于庞大,单靠Collection一个是没办法完成所有
公共
方法的抽取,所以出现了两个子接口,而这两个子接口的子类才是真正的执行者
2:List的特点
1:有序集合(存取一致)
2:元素可以重复
3:每个元素都要角标(既可以通过角标也可以通过元素操作)
3:List的功能:
由于继承的是Collection,所以除了拥有Collection中的方法外,还有自己特有的方法
1:增
boolean add(Object e);//原有的功能
void add(int index ,E element);//新功能
新的方法为什么没有返回值呢?
说真的,它应该也有返回类型的,但是由于是后出来的,所以它的异常被封装处理了,所以没有返回值
类型
boolean
addAll(Collection<? extends T>
);//原有功能
boolean addAll(int
from,Collection<? extends T>
t);//新功能更
不足之处:
我感觉它少封装了一个方法,就是boolean addAll(int from,int
to,Collection<? extends T> t)应该
是截取一个集合到另一个集合中
subList(int
from,int to,Collection<? extends T>
c);
2:删;
boolean remove(E e);//原有方法
boolean remove(int index);//新方法
boolean removeAdd(Collection<?
extends T> c);
void clear();
3:查
E get(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
4:包含与判断
boolean contains(Object c);
boolean containsAll(Collection<?
extends T> c);
boolean isEmply();
int size();
5:取所有元素
1:父类中的方法(Itrator),在操作的时候,数组不能改变
2:特有方法
ListItrator在操作的时候,数组可以自由改变
List子类
List 有2个子类
1:首先看ArrayList这个子类
我们说过,只有到了List的子类,才可以知晓他们各自具有的特点,才可以说他们具体的用途,所以就让
我们拭目以待吧
1:Arraylist特点
1:其内部封装了一个可变长度的数组,默认大小为10
2:由于每个元素都有下标,所以查询速度很快。
2:什么时候是使用?
当需要查询数据的时候使用最好
2:LinkedList集合
有人会问,既然ArrayList那么的好用,为什么还要出现LinkedList呢?
因为ArrayList数组的长度是可变的,我们查询的时候没有问题,但是当我们重复的删除添加一个元
素的时候,整个数组都在进行着重新的变动,这就又带来了效率的下降,所以就出现了LinkedList,
所以我们来看其有什么特点吧
1:
LinkedList特点
1:底层结构为链表结构,长度可变
2:由于是链表所以增加与删除第一与最后一个的速度快
2:什么时候用呢?
当需要频繁对元素进行增删的时候用最好
3:刚才之所以没有提ArrayLit的功能,主要是因为它继承了父类中的,自己本身没有什么特殊的方法,但
是LinkedList不同因为他又自己特有的方法,具体如下
1:删除:
boolean
removeFirse();//有异常
boolean removeLast();
新的为
boolean pollFirst();
boolean
pollFirst();//返回null,没有异常
获取:
boolean
getFirst();
boolean getLast();
新的为
boolean peekFirst();
boolean peekLast();
说完List,开始说SetSet与List一样,也是Collection的子类,也是接口
set具有以下特点
1:元素无序
2:元素不重复
set及其子类没有太多自己特有的方法,所以省略接下来重点看其子类
HashSet集合
1:特点:
1:底层是hash表结构,所以查询速度比较快
2:元素不能重复
2:什么时候使用?
当元素无序且不重复的时候使用,这就是涉及到了一个问题,怎么判断元素是否重复,怎么把重复的
元素过滤掉呢?
因为系统是根据hash算法算出每个元素的具体值,所以确保了元素的唯一性。但是万一他们有相同的
hash值的时候,该怎么办?
这时候就需要判断他们的内容是否相同,如果2个值的hash值相同,但是内容不同他们也是不同的元
素,这时系统会根据别的条件重新算hash值。虽然底层的hash算法可以确保元素的唯一,但是其
equals方法却不能,因为equals继承的是Object的方法,其比较的是指针是否相 而不是内容是否相
同,所以我们在使用HashSet的时候,必须覆写hashCode与equals方法。
如果HashCode值不同,则不判断equals
如果hashCOde值相同,则判断equals中内容是否相同,如果相同,则为同一个值,不同,则为不同的
值,存到集合中。
判断两个对象是否是同一个:Hashcode值与内容
3:如果我想让存取是一致的,那么我们需要 HashSet的子类LinkHashSet TreeSet集合
1:特点
1:底层是二叉树结构
2:进行自然排序,所以存取的数据是有序的
2:什么时候使用?
当需要存入的数据是有序的时候使用
3:TreeSet实现排序的方式?
1:可以让存入的元素自己具备排序功能,需要实现Comparable接口中的computo方法但是更多的时
候,要存入的元素不是我们写的,而是别人写好的,这时候我们要是先排序,该怎么办呢?
这就有了第2中方式:传入比较器
2:在TreeSet的构造方法中,可以通过传入比较器来实现按指定的方式进行比较现比较器需要实现
comparator接口中未实现的方法即可
到此为止我把自己所理解的Collection集合已经详细的总结完毕,望多多提出意见与建议。
|