java 中的集合类

来源:互联网 发布:临沂知豆电动车租赁 编辑:程序博客网 时间:2024/04/28 20:27

关键字: java collection 集合

一、Jdk集合框架

Jdk集合框架主体结构图显示了Jdk集合框架类结构。Jdk集合由collection接口牵头,Set、List和Map承担主角,用数据结构Tree,Array,Hash,Link作为具体实现手段,组成了一个在功能和性能上相当不错的框架。整个框架由主体结构和辅助结构组成,主体结构形成了框架基础,辅助结构为使用框架提供了便利。

 

jdk的集合框架的主体结构:

接口 简述 实现 操作特性 成员要求 Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。 TreeSet 外部有序地遍历成员;附加实现了SortedSet, 支持子集等要求顺序的操作 成员要求实现caparable接口,或者使用 Comparator构造TreeSet。成员一般为同一类型。 LinkedHashSet 外部按成员的插入顺序遍历成员 成员与HashSet成员类似 List 提供基于索引的对成员的随机访问 ArrayList 提供快速的基于索引的成员访问,对尾部成员的增加和删除支持较好 成员可为任意Object子类的对象 LinkedList 对列表中任何位置的成员的增加和删除支持较好,但对基于索引的成员访问支持性能较差 成员可为任意Object子类的对象 Map 保存键值对成员,基于键找值操作,compareTo或compare方法对键排序 HashMap 能满足用户对Map的通用需求 键成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。 TreeMap 支持对键有序地遍历,使用时建议先用HashMap增加和删除成员,最后从HashMap生成TreeMap;附加实现了SortedMap接口,支持子Map等要求顺序的操作 键成员要求实现caparable接口,或者使用Comparator构造TreeMap。键成员一般为同一类型。 LinkedHashMap 保留键的插入顺序,用equals 方法检查键和值的相等性 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。 IdentityHashMap 使用== 来检查键和值的相等性。 成员使用的是严格相等 WeakHashMap 其行为依赖于垃圾回收线程,没有绝对理由则少用  

 

  • facade类──Collections类

    Collections类包含了对框架中集合的普遍性操作,充当fa?ade。这些操作都被实现为静态函数,分为几下几类:

    1. 最大最小函数,对于某个集合,寻找最大最小成员(或键成员),要求成员都必须实现comparable接口;
    2. 生成不可更改的singleton集合(singleton集合为包含一个成员的集合);
    3. 对list进行排序、重组、倒序操作;
    4. 对list进行填充、批量置换、和快速搜索操作;
    5. 对集合进行同步化,以便适应多线程环境;
    6. 对集合进行不可更改修饰,返回不可更改的集合视图。
  • 等值方法一 ──equals(Object o)方法

    equals方法实现了一个等价关系:

    • 自反性: 对于任何对象x, x.equals(x)必须返回true;
    • 对称性: 对于任何对象x和y, x.equals(y)==true 当切仅当y.equals(x)==true;
    • 传递性: 对于任何对象x,y,z,如果x.equals(y)==true和y.equals(z)==true,则x.equals(z)==true;
    • 一致性: 对于任何对象x和y,只要没有对x,y进行修改,多次的x.equals(y) 调用应该返回相同的值;
    • 对于任何non-null 对象x, x.equals(null)==false。

    Object类中这个方法被实现为严格相等,也就是如果比较的两个对象是同一对象,即==操作为true,则返回true。所以如果想在集合中搜索内容相等的成员对象或在map中获取内容相等的键映射的值,成员对象(或键对象)的类必须覆盖equals(Object o)方法。

  • 等值方法二──hashCode()方法

    这个方法返回一个对象的hash 代码,在hashtable数据结构实现的集合中,它决定了这个对象被放到哪个bucket中。而equals方法则是进一步到bucket寻找具体对象的依据。

    为了hashtable数据结构能正常工作,hashCode方法的通用协议是:equals方法定为相等的两个对象的hashCode()返回的整数一定相同。只有这样才能在hashtable数据结构中找到这个对象。而equals方法定为不相等的两个对象的hashCode()返回的整数可以不相同,如果相同则为哈西冲突。所以尽量保证equals方法定为不相等的对象的hashCode()返回的整数不相同。

    类Object实现的hashCode使用对象的内部地址转化为整数返回,使得o1.equals(o2)当且仅当o1.hashCode()== o2.hashCode()。

  • 比较接口一──接口Comparable

    这个接口要求全序,也叫自然排序,实现了这个接口的类的compareTo称为自然比较方法。

    Collections.sort方法能对一个实现了这个接口的类的对象的列表自动排序。在没有指定comparator的情况下,这样的对象同时也能作为排序map的键或排序set的成员。

    如果一个类的任意两个实例e1和e2,(e1.compareTo((Object)e2) == 0)和e1.equals((Object)e2)有同样的逻辑值,我们就说这个类的自然排序和equals方法一致。另外e1.compareTo(null)应该抛出NullPointerException。

    强烈要求保持这种一致性,否则没有显示指定comparator的排序set(或map)将会破坏set (或 map)的普遍接口协议,因为这些接口协议用equals方法决定成员身份。

    compareTo方法的协议为:

    1. 当e1 < e2 时(e1.compareTo((Object)e2) <0;
    2. 当e1 > e2 时(e1.compareTo((Object)e2)〉0;
    3. 当e1.equals(e2) 时(e1.compareTo((Object)e2) ==0
    4. 当两个对象无法比较时,应该抛出ClassCastException 异常。

    在j2sdk1.4中,下面的类实现了这个接口:

    BigDecimal, BigInteger, Byte, ByteBuffer, Character, CharBuffer, Charset, CollationKey, Date, Double, DoubleBuffer, File, Float, FloatBuffer, IntBuffer, Integer, Long, LongBuffer, ObjectStreamField, Short, ShortBuffer, String, URI。

    二、常见集合接口和集合类

    java 代码
    1. import java.util.List;   
    2. import java.util.ArrayList;   

      1、java.util.ArrayList

    3. List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,除了此类是不同步的。)

      sizeisEmptygetsetiteratorlistIterator 操作都以固定时间运行。add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。其他所有操作都以线性时间运行(大体上讲)。与用于 LinkedList 实现的常数因子相比,此实现的常数因子较低。

      每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。

      在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

      注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问:

              List list = Collections.synchronizedList(new ArrayList(...));

      此类的 iteratorlistIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

      注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。

      此类是 Java Collections Framework 的成员。

      Since: 1.2

      2、java.util.LinkedList

      List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 getremoveinsert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列 (deque)。

      此类实现 Queue 接口,为 addpoll 等提供先进先出队列操作。其他堆栈和双端队列操作可以根据标准列表操作方便地进行再次强制转换。虽然它们可能比等效列表操作运行稍快,但是将其包括在这里主要是出于方便考虑。

      所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。

      注意,此实现不是同步的。如果多个线程同时访问列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法来“包装”该列表。最好在创建时完成这一操作,以防止对列表进行意外的不同步访问,如下所示:

           List list = Collections.synchronizedList(new LinkedList(...));

      此类的 iteratorlistIterator 方法返回的迭代器是快速失败 的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过迭代器自身的 removeadd 方法,其他任何时间任何方式的修改,迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来不确定的时间任意发生不确定行为的风险。

      注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何硬性保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

      此类是 Java Collections Framework 的成员。

      Since: 1.2

      3、Vector 类提供了实现可增长数组的功能,随着更多元素加入其中,数组变的更大。在删除一些元素之后,数组变小。

    4. java.util.Vector<e></e>

      java.lang.Object  继承者 java.util.AbstractCollection<e></e>      继承者 java.util.AbstractList<e></e>          继承者 java.util.Vector<e></e>
      所有已实现的接口:
      Serializable, Cloneable, Iterable<e></e>, Collection<e></e>, List<e></e>, RandomAccess
      直接子类:Stack

      Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。

      每个向量会试图通过维护 capacitycapacityIncrement 来优化存储管理。capacity 始终至少应与向量的大小相等;这个值通常比后者大些,因为随着将组件添加到向量中,其存储将按 capacityIncrement 的大小增加存储块。应用程序可以在插入大量组件前增加向量的容量;这样就减少了增加的重分配的量。

      从 Java 2 平台 v1.2 开始,已改进此类以实现 List,这样它就成为了 Java 的集合框架的一部分。与新集合的实现不同,Vector 是同步的。

      由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的:如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生不确定行为的风险。Vector 的 elements 方法返回的 Enumeration 不是 快速失败的。

      注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug。
        Vector 有三个构造函数:

        public Vector(int initialCapacity,int capacityIncrement)
        public Vector(int initialCapacity)
        public Vector()

        Vector 运行时创建一个初始的存储容量initialCapacity,存储容量是以capacityIncrement 变量定义的增量增长。初始的存储容量和capacityIncrement 可以在Vector 的构造函数中定义。第二个构造函数只创建初始存储容量。第三个构造函数既不指定初始的存储容量也不指定capacityIncrement。

        Vector 类提供的访问方法支持类似数组运算和与Vector 大小相关的运算。类似数组的运算允许向量中增加,删除和插入元素。它们也允许测试矢量的内容和检索指定的元素,与大小相关的运算允许判定字节大小和矢量中元素不数目。

      4、java.util.Hashtable

      java.lang.Object
        继承者 java.util.Dictionary
            %	
				<ul class=

    5. JAVA中的集合类
    6. JAVA中的集合类
    7. JAVA中的集合类
    8. JAVA中的集合类
    9. JAVA中的集合类
    10. JAVA中的集合类 - -
    11. JAVA中的集合类
    12. java中的集合类
    13. Java中的集合类
    14. JAVA中的集合类
    15. Java中的集合类
    16. Java中的集合类
    17. java 中的集合类
    18. JAVA中的集合类
    19. java中的集合类
    20. Java中的集合类
    21. java中的集合类
    22. java 中的集合类
    23. Oracle数据库的ORA-00257故障解决过程
    24. 将FxCop集成到Visual Studio开发环境中使用
    25. 让JSP页面不缓存 设置JSP页面立即过期
    26. spring学习笔记:bean的配置
    27. 传智播客Spring视频教程学习笔记7
    28. java 中的集合类
    29. [Oracle] 如何解决ORA-04031 错误
    30. 开发EditPlus的“插件
    31. 看看能不能用?
    32. Stickies tips 工具
    33. 一个跨平台的 C++ 内存泄漏检测器(转载)
    34. 生活在广州
    35. 应用程序引用的程序集文件基目录更改后,添加配置文件使应用程序可用
    36. 内核空间重启系统
    原创粉丝点击