笔记:Java 集合相关

Collection接口

java Api并没有实现该接口的实现类,但是提供了三个子接口分别是:List,Set,Queue。下面我们对这三个子接口进行分析:

1、List 接口存储一组允许重复,有序(插入顺序)的对象,有下标,插入顺序作为遍历的顺序

2、Set 接口存储一组唯一,无序的对象 没下标 插入的顺序跟遍历的顺序是不一样的

3、Queue  队列 一个队列就是一个先入先出(FIFO)的数据结构

一、首先我们先讲讲List

List 接口存储一组允许重复,有序(插入顺序)的对象(包括null),可以通过索引(下标)来进行访问

List 接口的常用实现类有ArrayList,LinkedList 以及 Vertor,在使用List集合时,通常情况下声明为List类型,实例化时根据实际情况的需要,实例化为ArrayList或LinkedList。

三者的主要特征是:

1.ArrayList 是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组. 
2.LinkedList 是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList 
3.Vector 和ArrayList类似,但属于线程安全类。如果你的程序本身是线程安全的(thread-safe,没有在多个线程之间共享同一个集合/对象),那么使用ArrayList是更好的选择。

总结就是  ArrayList 易于存取,不易于增删;LinkedList 易于增删,不易于存取;Vector 是线程安全的(却不常用)

二、然后是 Set

List 接口的常用实现类有HashSet,TreeSet

三者的主要特征是:

1、HashSet  存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。所以是无序(不会按照存入顺序进行排序);又因为 HashSet 会通过元素的hashcode()和equals方法进行判断元素是否重复。因为set 是不可重复的,所以存入的数据要满足:hashcode()不同,或 equals 为false;注意是  或者 的关系;

线程不安全,存取速度快。底层是以hash表实现的。

2、TreeSet

TreeSet是SortedSet接口的实现类,正如SortedSet名字所暗示的,TreeSet可以确保集合元素处于排序状态。

TreeSet中所谓的有序,不同于之前所讲的插入顺序,而是通过集合中元素属性进行排序方式来实现的。
TreeSet支持两种排序方法:自然排序定制排序。在默认情况下,TreeSet采用自然排序。

TreeSet是根据红黑树结构找到集合元素的存储位置。

红黑树算法的规则: 左小右大。

既然TreeSet可以自然排序,那么TreeSet必定是有排序规则的。

1:让存入的元素自定义比较规则。

2:给TreeSet指定排序规则。

总结:hashSet扩展性不好,但是查和插入(删除也一样)速度都不错;treeSet扩展性不错,查速度也不错,就是插入会速度慢点。
 

三、Queue

队列的详细解释网上有篇文章写得很详细,推荐一下:https://www.cnblogs.com/lemon-flm/p/7877898.html

队列的操作

  add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
  remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
  element  返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常
  offer       添加一个元素并返回true       如果队列已满,则返回false
  poll         移除并返问队列头部的元素    如果队列为空,则返回null
  peek       返回队列头部的元素             如果队列为空,则返回null
  put         添加一个元素                      如果队列满,则阻塞
  take        移除并返回队列头部的元素     如果队列为空,则阻塞

我们有阻塞操作put和take。put方法在队列满时阻塞,take方法在队列空时阻塞。

1、LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素

2、ArrayBlockingQueue 在构造时需要指定容量, 并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。

3、PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。

4、DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。

猜你喜欢

转载自blog.csdn.net/atmknight/article/details/82591583
今日推荐