Java集合类

Java集合类:

Java结合类基本概念:Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:

  • Collection:一组"对立"的元素,通常这些元素都服从某种规则
  1. List必须保持元素特定的顺序
  2. Set不能有重复元素
  3. Queue保持一个队列(先进先出)的顺序
  • Map
  1. 一组成对的"键值对"对象

Collection和Map的区别在于容器中每个位置保存的元素个数:

  1. Collection 每个位置只能保存一个元素(对象)
  2. Map保存的是"键值对",就像一个小型数据库。我们可以通过"键"找到该键对应的"值"

Java结合类架构层次关系

Interface Iterable

  • 迭代器接口,这是Collection类的父接口。实现这个Iterable接口的对象允许使用foreach进行遍历,也就是说,所有的Collection集合对象都具有foreach可遍历行。这个Iterable接口只有一个方法:iterator()。它返回但其哪集合对象的反省<T>迭代器,用于之后的遍历操作

一、Collection

Collection是最基本的集合接口,一个Collection代表一组Object的集合,这些Object呗称为Collection的元素。Collection是一个接口,用于提供规范定义,不能被实例化使用

1)Set:Set集合类似一个罐子,丢进Set集合里面的多个对象之间没有明显的顺序。Set不能包含有重复元素(记住,这是整个Set类层次的共有属性)。

  • Set判断两个对象相同不能使用“==”操作符,而是根据equals方法。也就是说,在我们加入一个新元素的时候,如果这个新元素对象和Set中已有对象进行equals比较都返回false,则Set就接收这个新元素对象,否则拒绝。
  • 因为Set的这个制约,在使用Set集合的时候,应该注意两点:
  1. 为Set集合里的元素的实现类实现一个有效的equals方法
  2. 对Set的构造函数,传入的Collection参数不能包含重复的元素。

1.1)HashSet   equals()决定是否可以加入HashSet、而hashCode()决定存放的位置,它们两者必须同时满足才能允许一个新元素加入HashSet

  • HashSet是Set接口的典型实现,HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和插好性能,hash集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且hashCode值也想等。

1.1.1)LinkedHashSet   元素的顺序总是与添加顺序一致,且不允许集合元素重复

  • LinkedHashSet和HashSet不同的是,它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时将会有很好的性能(链表很适合进行遍历)

1.2)SorteSet:此接口主要用于排序操作,即实现此接口的子类都属于排序的子类

1.2.1)TreeSet   与HashSet集合采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。

  • TreeSet支持两种排序方式: 自然排序、定制排序
  1. 自然排序:(元素对象实现Comparable接口,实现一个比较方法):采用自然顺序的TreeSet 集合中的元素对象都必须实现了Comparable接口,而且应该是同一个类的多个实例,否则可能导致ClassCastException异常
  2. 定制排序:(传入一个Comparator对象,定义个比较方法):创建TreeSet 时,传入一个Comparator对象,该对象负责对队列中的所有元素进行排序
  • TreeSet是SortedSet接口的实现类,可以确保集合元素处于排序状态

1.3)EnumSet

  • EnumSet是一个专门为枚举类设计的集合类,EnumSet中所有元素必须指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。EnumSet的集合元素也是有序的,他们以枚举值在EnumSet类中的定义顺序决定集合元素的顺序。

2)List  :除了Collection固有的iterator()方法,List还额外提供了一个listIterator()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iterator接口,提供了专门操作List的方法。

  • List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许加入重复元素,因为他们可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引

2.1)ArrayList 

  • 如果一开始就知道ArrayList集合需要保存多少元素,则可以在创建它们时就指定initialCapacity大小,这样可以减少重新分配的次数,提高性能,ArrayList还提供了如下方法来重新分配Object[]数组
  • rrayList是基于数组实现的List类,它创建了一个动态的增长的允许再分配的Object[]数组。ArrayList容量不足时,“新的容量”=“(原始容量x3)/2 + 1”

2.2)Vector

  • Vetcot和ArrayList在用法上几乎完全相同,Vector是一个古老的集合,但随着JDK1.2之后,Java将Vector改为实现List接口,统一归入集合框架体系里。Vector是线程安全的,Vector不支持序列化,Vector的容量增长与“增长系数有关”,若指定了“增长系数”,且“增长系数有效(即,大于0)“;那么,每次容量不足时,“新的容量”=“原始容量+增长系数”。若增长系数无效(即,小于/等于0),则“新的容量”=“原始容量 x 2”。

2.2.1)Stack  注意Stack的后进先出的特点

  • Stack是Vector提供的一个子类,用于模拟栈这种数据结构

3)Queue

  • Queue用于模拟队列这种数据结构,队列不允许随机访问队列中的元素。

3.1)PriorityQueue PriorityQueue不允许插入null元素,它还需要对队列元素进行排序,PriorityQueue的元素有两种排序方式

  • 1) 自然排序:(元素对象实现Comparable接口,实现一个比较方法):采用自然顺序的PriorityQueue集合中的元素对象都必须实现了Comparable接口,而且应该是同一个类的多个实例,否则可能导致ClassCastException异常
  • 2) 定制排序:(传入一个Comparator对象,定义个比较方法):创建PriorityQueue队列时,传入一个Comparator对象,该对象负责对队列中的所有元素进行排序
  • 关于自然排序、定制排序的原理和之前说的TreeSet类似
  • PriorityQueue并不只一个比较标准的队列实现,PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序,这点从它的类名也可以看出

3.2)Deque:Deque接口代表一个双端队列,双端队列可以同时从两段来添加删除数据,因此Deque的实现类可以当成队列使用,也可以当成栈使用

3.2.1) ArrayDeque

  • 是一个基于数组的双端队列,和ArrayList类似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出该数组的容量时,系统会在底层重新分配一个Object[]数组来存储集合元素

3.2.2) LinkedList

  • LinkedList同时表现出了双端队列、栈的用法。功能非常强大 LinkedList是List接口的双向链表非同步实现

二、Map

当使用自定义类作为HashMap、Hashtable的key时,如果重写该类的equals(Object obj)和hashCode()方法,则应该保证两个方法的判断标准一致--当两个key通过equals()方法比较返回true时,两个key的hashCode()的返回值也应该相同

Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较结果总是返回false。关于Map,我们要从代码复用的角度去理解,Java是先实现了Map,然后通过包装了一个所有value都为null的Map就实现了Set集合。Map的这些实现了和子接口中key的存储形式和Set集合完全相同

1)HashMap:

  • 和HashSet集合不能保证元素的顺序一样,HashMap也不能保证顺序,并且类似于HashSet判断两个key的标准也是通过equals方法比较和hashCode值比较

1.1)LinkedHashMap

  • LinkedHashMap也是用双向链表来维护key-value对的次序,该链表负责维护Map的迭代顺序,与key-value对的插入顺序一致(注意和TreeMap对所有的key-value进行排序操作进行区分)

2)Hashtable

  • 是一个古老的Map实现类

2.1)Properties 

  • roperties对象在处理属性文件时特别方便,Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的key-value对写入到属性文件中,也可以把属性文件中的属性名-属性值加载到Map对象中。

3)SortedMap

  • 正如Set接口派生出SortedSet子接口,SortedSet接口有一个TreeSet实现类一样,Map接口也派生出一个SortedMap子接口,SortedMap接口也有一个TreeMap实现类

3.1) TreeMap

  • TreeMap就是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap可以保证所有的key-value对处于有序状态。同样,TreeMap也有两种排序方式:自然排序、定制排序。

4)WeakHashMap

  • WeakHashMap与HashMap的用法基本相似。区别在于,HashMap的key保留对实际对象的强引用,这意味着只要该HashMap对象不被销毁,该HashMap所引用的对象就不会被垃圾回收。但WeakHashMap只保留了对实际对象的弱引用,这意味着如果WeakHashMap的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,当垃圾回收了该key所对应的实际对象之后,WeakHashMap也可能自动删除这些key所对应的key-value对

5)IdentityHashMap

  • IdentityHashMap的实现机制与HashMap基本相似,在IdentityHashMap中,当且仅当两个key严格相等(key1 == key2)时,IdentityHashMap才认为两个key相等

6) EnumMap

  • EnumMap是一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值。创建EnumMap时必须显式或隐式指定它对应的枚举类。EnumMap根据key的自然顺序(即枚举值在枚举类中的定义顺序)

三、Java集合类的应用场景代码

LinkedList(实现了Deque双端队列接口)、Vector、ArrayList都是继承AbstractList的

  • java提供的List就是一个"线性表接口",ArrayList(基于数组的线性表)、LinkedList(基于链的线性表)是线性表的两种典型实现
  • Queue代表了队列,Deque代表了双端队列(既可以作为队列使用、也可以作为栈使用)
  • 因为数组以一块连续内存来保存所有的数组元素,所以数组在随机访问时性能最好。所以的内部以数组作为底层实现的集合在随机访问时性能最好。
  • 内部以链表作为底层实现的集合在执行插入、删除操作时有很好的性能
  • 进行迭代操作时,以链表作为底层实现的集合比以数组作为底层实现的集合性能好

HashMap和Hashtable的效率大致相同,因为它们的实现机制几乎完全一样。但HashMap通常比Hashtable要快一点,因为Hashtable需要额外的线程同步控制

TreeMap通常比HashMap、Hashtable要慢(尤其是在插入、删除key-value对时更慢),因为TreeMap底层采用红黑树来管理key-value对,需要在插入和删除的时候通过旋转保持红黑树的结构

使用TreeMap的一个好处就是: TreeMap中的key-value对总是处于有序状态,无须专门进行排序操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值