Java基础之集合框架

java集合架构支持3种类型的集合:规则集(Set),线性表(List),和图(Map),分别定义在Set,List,Map中。

Set实例存储一组互不相同的元素(集合),List实例存储一组顺序排列的元素(表),Map存储一组 对象---关键值的映射

 

集合中存储的是Java对象的引用,是一个引用的集合,这个引用指向相应的对象空间 ,而不是集合本身存储的对象

集合中不可以存储基本数据类型值,基本数据类型也可以装入集合,但其内部是先自动装箱成包装类对象,再存入集合


总的架构如下,非常重要,包含继承关系,实现的分类,一目了然:集合分为Map 接口和Collection接口 ,这两个接口是Java集合框架的根接口

Collection接口: 

       Set接口:不可重复  没有索引

            HashSet具体类 : 使用哈希算法去重复, 效率高, 但元素无序

            LinkedHashSet具体类 : HashSet的子类, 原理相同, 除了去重复之外还能保留存储顺序

            TreeSet具体类 :使用二叉树算法排序, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列

       List接口: 可重复, 有存储顺序(有索引),存和取有序
            ArrayList具体类 :数组实现, 增删慢, 查找快 线程不安全

            LinkedList具体类 : 链表实现, 增删快, 查找慢 线程不安全

            向量类Vector具体类 :  数组实现, 原理和ArrayList相同, 但线程安全

            Stack具体类


Map接口:
       HashMap类:使用哈希算法对键去重复, 效率高, 但无序  ,允许null键和null值 ,线程不安全

       LinkedHashMap类 :使用哈希算法去重复, 并且保留存储顺序  ,线程不安全

       TreeMap类: 使用二叉树算法排序, 可以自定义顺序  。可以对Map集合中的键进行排序。,线程不安全

       Hashtable :类似HashMap, 线程安全, 效率略低, 不允许null键和null值 

   Properties : 继承 HashTable  比 Hashtable 更严格 属性列表中每个键及其对应值都是一个字符串。 
    
---------------------------------------------------------------------------------------------------------------------------------------------------



1)先来说Collection接口,它是处理对象集合的根接口,提供了一些公用方法,size,Iterator,add,remove什么的

2)Set和List接口都扩展自Collection,Set就是高中数学里所说的集合,不允许重复,无序。List就像一个表,可以重复,元素在表里有顺序的放着。

3)然后来说Set接口的3种实现:

  HashSet的对象必须实现hashCode方法,javaAPI大多数类实现了hashCode方法。根据hashCode()返回值 来决定对象的所放的位置 

     HashSet底层是基于HashMap实现的,HashSet中的所有元素是由HashMap中的Key来保存的,只不过只提供了Key的访问,Value存一个静态的Object对象PRESENT,不提供访问

HashSet如何保证该集合的元素唯一性呢?

HashSet中两个对象hashCode()方法返回值相等,并且两个对象通过equals方法比较返回true, 才判断两个元素是相同的,向集合中添加相同元素是存不进去的,不是覆盖
  LinkedHashSet实现了对HashSet的扩展,支持规则集内元素的排序,在HashSet中元素是没有顺序的,而在LinkedHashSet中,可以按元素插入集合的顺序进行提取
  TreeSet保证集中的元素是有序的,有2种方法可以实现对象之间的可比较性:1,添加到TreeSet的对象实现了Comparable接口;2,给规则集的元素指定一个比较器(Comparator)

    TreeSet底层是用TreeMap进行存储的,实际上是把TreeSet中的元素保存在TreeMap中的Key中, TreeMap采用红黑树排序二叉树的来保存集合中的Entry,支持自然排序和定制排序,默认情况下采用自然排序 
自然排序 :TreeSet会调用元素的compareTo(Object obj)方法(返回一个整数,返回0表示相等,放在同一位置) 来比较元素之间的大小 ,然后按升序进行排序 这就是自然排序

 存入TreeSet集合中的元素必须实现compareble接口,否则会报异常,判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。 

TreeSet对元素进行排序的方式一:
让元素自身具备比较功能,元素需要实现Comparable接口。覆盖compareTo方法。

如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。
使用提示:

如果希望按照元素插入集合的顺序进行提取元素,用LinkedHashSet,它的元素按添加的顺序存储

如果没有上述需求,应该用HashSet,它的效率比LinkedHashSet高

LinkedHashSet只是按照添加的的先后顺序在存储时保持顺序,要给集合元素添加顺序属性,需要使用TreeSet(集合元素有排序关系)。


4)再来说List的几种实现

最重要的的当然是ArrayList(不同步)和LinkedList,一个使用数组实现的动态扩展容量的list,一个是链式实现的list。

ArrayList内部封装了一个动态再分配的Object[] 数组,该类对象有一个capacity属性用来表示此数组的和长度,如不指定初始长度为10,当增加元素超过该长度,capacity会自动增加为原来的1.5倍
LinkedList : 实际上就是一个双向链表,不仅实现了List接口,还实现了Deque接口   具有双向队列和栈的特性  线程不安全的 
还有就是Vector(同步)类,它除了包含访问和修改向量的同步方法之外,跟ArrayList一样。

即使需要保证线程安全时也不建议使用Vector,可以使用Collections工具类中的synchronizedList方法将ArrayList包装成线程安全的取代Vector

最后就是Stack类,它继承自Vector类,,但一般只作为栈的功能来使用,不要去使用Vector里面的功能


5)Map

Map是映射,跟前面的Set和List有本质的区别。

散列图HashMap,链式散列图LinkedHashMap,树形图TreeHashMap是映射的3种实现,从名字上来说,有了上述Set的3种实现的分析,这个也是类似的。

HashMap:效率高
LikedHashMap:按照添加顺序存储,可以按添加顺序取出
TreeHashMap:排序性

---------------------------------------------------------------------------------------------------------------------------------------------------


Collections类和Arrays类:

Collections类(注意不是Collection):提供了许多静态的方法来管理集合,线性表(大多数是来操作线性表的,比如对线性表复制,排序之类的,参见API)

Arrays类:提供了对数组排序,查找,比较,填充元素的各种静态方法。

集合可以转为Object[]对象数组,但不是不能转为基本类型的数组,因为集合里面放的是对象

----------------------------------------------------------------------------------------------------------------------------------------------------

迭代(遍历)

(1).List
* a.普通for循环, 使用get()逐个获取
* b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
* c.增强for循环, 只要可以使用Iterator的类都可以用
* d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
(2).Set
* a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
* b.增强for循环, 只要可以使用Iterator的类都可以用

(3).Map
* keySet():   得到所有的键组成的Set, 遍历Set得到每一个键, 然后再分别获取值
* entrySet(): 得到所有的Entry组成的Set, 遍历Set得到每一个Entry, 再分别getKey()和getValue()


(4).迭代时删除的问题
* a.for循环: 删除时由于后面的元素会向前移动, 所以删除之后循环变量要--
* b.迭代器:   使用迭代器遍历集合要删除元素时必须使用Iterator中的remove()否则会抛出异常
* c.增强for循环: 不能删除

--------------------------------------------------------------------------------------------------------------------------------------------------

posted @ 2016-07-30 20:47  adwars  阅读(184)  评论(0编辑  收藏  举报