Java的集合框架是Java中很重要的一环,Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。Java平台的完整集合框架如下图所示:

   

  上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。

  发现一个特点,上述所有的集合Collection类,都实现了Iterator接口,(Map中并没有实现这个接口),这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口ListIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。

  • 如果是Iterator接口,那么在遍历集合中元素的时候,只能单向遍历,只能通过next()访问下一个元素,依次往后遍历,被遍历后的元素不会在遍历到。所有集合均实现了这个接口,比如HashSet,HashMap;
  • 而如果是ListIterator接口,那么在遍历集合中元素的时候,可以实现双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,更加灵活。但是只有List的子类才实现了这个接口,比如ArrayList。

  还有一个特点就是抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。

  将一些抽象类去掉之后的简化版如下图所示。

  
  下面简单介绍下每一种集合类型的特点:

  • Collection:每个“槽”只有一个元素

    • Set:每个元素必须是唯一的,不能含有重复的元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。不保证维护元素的顺序。

      • HashSet***:主要的特点是:存入HashSet的元素必须定义hashCode()方法采用散列的存储方法,所以没有顺序。这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致。底层的物理结构是哈希表

        • LinkedHashSet*:主要特点是:具有HashSet的查询速度,且背部使用链表维护元素的顺序(插入的次序),存入LinkedHashSet的元素必须定义hashCode()方法,底层的物理结构是链表结合哈希表
      • TreeSet*:主要特点是是:保持次序的Set,存入TreeSet的元素必须实现Comparable接口,在加入元素时会自动进行排序。底层的物理结构是红黑树
    • List:将以特定次序存储元素,可以重复。
      • ArrayList***:主要特点是:长于随机访问元素,但是在List中间插入和移除元素时较慢,加入元素的顺序就是其存放元素的顺序。底层的物理结构是数组
      • LinkedList***:只要特点是:随机访问速度较慢,可以在任何位置进行高效地插入和删除操作的有序序列。底层的物理结构是双向链表LinkedList具有直接实现Stack(栈)的所有功能的方法,因此可以直接将LinkedList作为Stack使用。LinkedList也实现很多方法支持Quene(队列)的行为,并且其也实现了Quene接口,因此LinkedList也可以用作Quene的一种实现,可以将LinkedList向上转型为Quene。
      • Vector:主要特点是:和ArrayList功能和特点基本类似,不同的地方在于Vector是线程安全的,所以速度相对慢一些。底层的物理结构也是数组。现在基本上不怎么用了
        • Stack:现在不用了,可以用LinkedList来当做Stack.
    • Quene:先进先出的容器。从容器的一端放入事物,从另一端取出。一般用LinkedList来当做Quene.
  • Map:每个“槽”中存放的是键值对(key-value),可以使用键来查找值。
    • HashMap***:主要特点是:基于散列表的实现(取代了Hashtable)。插入和查询键值对的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器性能。

      • LinkedHashMap*:类似于HashMap,但是迭代遍历时,取得的键值对的顺序是其插入的次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点,而在迭代访问时更快,因为其用链表维护内部次序,
    • TreeMap**:基于红黑树的实现。加入TreeMap的元素会被自动排序,排序次序有Comparable或Comparator决定( Comparable和Comparator的区别)。是唯一带有subMap()方法的Map,可以返回一个子树。
    • Hashtable:线程安全的,同HashMap现在基本上不用了
    • WeakedHashMap:弱键(weak key)映射,允许释放映射所指向的对象
    • IdentifyHashMap:使用==代替equals()对“键”进行比较的散列映射。

代码实例:HashSetDemo

 package edu.sjtu.erplab.collection;

 import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class HashSetDemo { public static void main(String[] args) {
Set<String> set=new HashSet<String>(); set.add("a");
set.add("b");
set.add("c");
set.add("c");
set.add("d"); //使用Iterator输出集合
Iterator<String> iter=set.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:set)
{
System.out.print(e+" ");
}
System.out.println(); //使用toString输出集合
System.out.println(set);
}
}

代码实例:TreeSet


代码实例:ArrayListDemo

 package edu.sjtu.erplab.collection;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class ArrayListDemo {
public static void main(String[] args) {
List<String> arrList=new ArrayList<String>(); arrList.add("a");
arrList.add("b");
arrList.add("c");
arrList.add("c");
arrList.add("d"); //使用Iterator输出集合
Iterator<String> iter=arrList.iterator();
while(iter.hasNext())
{
System.out.print(iter.next()+" ");
}
System.out.println();
//使用For Each输出结合
for(String e:arrList)
{
System.out.print(e+" ");
}
System.out.println(); //使用toString输出集合
System.out.println(arrList);
}
}

代码实例:LinkedListTest

 package edu.sjtu.erplab.collection;

 import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class LinkedListTest { public static void main(String[] args) { List<String> a=new ArrayList<String>();
a.add("a");
a.add("b");
a.add("c");
System.out.println(a); List<String> b=new ArrayList<String>();
b.add("d");
b.add("e");
b.add("f");
b.add("g");
System.out.println(b); //ListIterator在Iterator基础上添加了add(),previous()和hasPrevious()方法
ListIterator<String> aIter=a.listIterator();
//普通的Iterator只有三个方法,hasNext(),next()和remove()
Iterator<String> bIter=b.iterator(); //b归并入a当中,间隔交叉得插入b中的元素
while(bIter.hasNext())
{
if(aIter.hasNext())
aIter.next();
aIter.add(bIter.next());
}
System.out.println(a); //在b中每隔两个元素删除一个
bIter=b.iterator(); while(bIter.hasNext())
{
bIter.next();
if(bIter.hasNext())
{
bIter.next();//remove跟next是成对出现的,remove总是删除前序
bIter.remove();
}
}
System.out.println(b); //删除a中所有的b中的元素
a.removeAll(b);
System.out.println(a);
}
}

最后,看到了一些关于集合架构源码剖析的文章,有兴趣可以看一下,多了解内部原理也是挺好的。

  各大类直接的区别可以参见:java中Map,List与Set的区别

  探索equals()和hashCode()方法

Java集合框架源码剖析:HashSet 和 HashMap:

  http://blog.jobbole.com/101493/

   java中的HashTable,HashMap和HashSet

注意:HashMap的初始化容量为16,负载因子为0.75,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大两倍。

   HashSet的内部结构就是HashMap,只是每个键值对的值都确定为一个常量对象PRESENT(private static final Object PRESENT = new Object();)

Java集合框架源码剖析:LinkedHashSet 和 LinkedHashMap:

  http://blog.jobbole.com/101724/

  

注意:LinkedHashSet 和 LinkedHashMap之间的关系和HashSet与HashMap之间的关系是一样的。只是在其中加入了双向链表的结构。插入的时候依然按照HashMap的方式插入,只是在元素之间用双向链表表示前后的顺序,所以查找和插入都很快速。

Java集合框架源码剖析:TreeSet 和 TreeMap:

  http://blog.jobbole.com/102230/

  java集合类TreeMap和TreeSet

注意:TreeSet 和 TreeMap之间的关系和HashSet与HashMap之间的关系是一样的。TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator)。TreeMap底层通过红黑树(Red-Black tree)实现,也就意着containsKey()get()put()remove()都有着log(n)的时间复杂度。

  红黑树的原理:

    http://blog.jobbole.com/103045/

    《Thinking In Algorithm》07.Red-Black Trees(红黑树)

Java集合框架源码剖析:ArrayList:

  http://blog.jobbole.com/101796/

  ArrayList与LinkedList的区别

注意:ArrayList的初始化容量为10,然后当其中的元素个数大于16*0.75时进行扩容,每次扩容会将容量扩大原先的1.5倍,eg:第一次扩容至10+10/2=15,第二次是15+15/2 = 22,以此类推。

Java集合框架源码剖析:LinkedList:

  http://blog.jobbole.com/101830/

注意:LinkedList中定义的双向链表的Node节点如下:

private static class Node<E> {
E item;
Node<E> next;
Node<E> prev; Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

Java基础——集合框架的更多相关文章

  1. 十五、Java基础---------集合框架体系以及List

    在介绍集合之前先说一下数组,正如我们所知,数组是某一类型数据的集合,强调的是数据,而且必须单一:集合框架的不同之处在于存储的数据类型没有任何限制,既可以存储基本数据类型(会自动提升为相应的包装类)也可 ...

  2. java基础--集合框架的认识

    一.集合框架 对于不知道存储数量和更复杂的方式存储对象用集合框架. 其中有几个常用的接口和实现类:Collection父接口.List接口,Set接口,Map接口, ArrayList实现类.Link ...

  3. 十七、Java基础---------集合框架之Map

    前两篇文章中介绍了Collection框架,今天来介绍一下Map集合,并用综合事例来演示. Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素, ...

  4. Java基础——集合框架(待整理)

    ArrayList 和 和 Vector 的区别 从代码的最终的操作形式上可以发现,代码的输出结果与之前是一样的,而且没有区别,但是两者的区别还在于其内部的组成上. No. 区别点 Vector Ve ...

  5. 十六、Java基础---------集合框架之Set

    写在前面的话,这篇文章在昨天就写好了,今天打开的时候一不小心将第二天的文章粘贴到了这篇文章,很不幸的是除了标题之外依然面目全非,今天带着沉痛的心情再来写这篇文章! 上篇文章介绍了Collection体 ...

  6. Java基础---集合框架---迭代器、ListIterator、Vector中枚举、LinkedList、ArrayList、HashSet、TreeSet、二叉树、Comparator

    为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储对 ...

  7. Java 基础 集合框架

    Java中的集合从类的继承和接口的实现结构来说,可以分为两大类: 1 继承自Collection接口,包含List.Set和Queue等接口和实现类. 2 继承自Map接口,主要包含哈希表相关的集合类 ...

  8. Java基础-集合框架-ArrayList源码分析

    一.JDK中ArrayList是如何实现的 1.先看下ArrayList从上而下的层次图: 说明: 从图中可以看出,ArrayList只是最下层的实现类,集合的规则和扩展都是AbstractList. ...

  9. Java基础-集合框架的学习大纲

    1.List 和 Set 的区别 2.HashSet 是如何保证不重复的 3.HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程环境下不安全)? 4.HashMap 的扩容过程 ...

随机推荐

  1. mysql 存储引擎

    什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合.    我们通常说的MySql数据库,sql server数据库等等 ...

  2. CSS3初学篇章_3(属性选择符/字体样式/元素样式)

    属性选择符  选择符  说明  E[att]  选择具有att属性的E元素.  E[att="val"]  选择具有att属性且属性值等于val的E元素.  E[att~=&quo ...

  3. 《ASP.NET1200例》ListView 控件与DataPager控件的结合&lt;一&gt;

    分页     在前一部分开始时介绍的原 HTML 设计中内含分页和排序,所以根据规范完整实现该网格的任务尚未完成.我们先分页,然后再排序. ListView 控件中的分页通过引入另一个新控件 Data ...

  4. EntityFramwork6连接MySql错误

    EntityFramwork6连接MySql错误 使用EF6连接MySql产生Exception: ProHub.ssdl(2,2) : 错误 0152: MySql.Data.MySqlClient ...

  5. Linux进程调度与切换

    2016-04-15 张超<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.分析 进程调度的时机与进程 ...

  6. c#调用Excel绘制图表

    c#调用Excel需要引用命名空间 using Microsoft.Office.Interop.Excel; 由于该程序不复杂,主要是根据不同数据画表和图,画的图像也并不复杂,因为画图和画表的操作会 ...

  7. 《前端之路》之 初识 JavaScript

    01 初识 JavaScript 作为在码农圈混迹了 四五年的老码畜来说,学习一门新的语言,就仿佛是老司机开新车一样 轻车熟路. 为什么会这么快呢? 因为各种套路啊- 任何一种计算机语言的最开始都是和 ...

  8. Linux shell 脚本报错:/bin/bash^M: bad interpreter: No such file or directory

    今天遇到一个很诡异的问题,一直运行很正常的shell脚本失败了,只是昨天增加了一个参数而已. 报错信息: /bin/bash^M: bad interpreter: No such file or d ...

  9. Java 公平锁与非公平锁学习研究

    最近学习研究了一下Java中关于公平锁与非公平锁的底层实现原理,总结了一下. 首先呢,通过其字面意思,公平与非公平的评判标准就是付出与收获成正比(和社会中的含义差不多一个意思).放到程序中,尤其是 在 ...

  10. Tomcat的manager app管理web项目

    1.在浏览器地址栏输入http://localhost:8080/进入,如下图所示: 2.在点击Manager App 前,首次使用则需要对tomcat目录下的conf/tomcat-users.xm ...