Java集合类——Set、List、Map、Queue接口

旧街凉风 提交于 2020-03-29 20:23:42

目录

  • Java 集合类的基本概念
  • Java 集合类的层次关系
  • Java 集合类的应用场景

一. Java集合类的基本概念

在编程中,常需要集中存放多个数据,数组是一个很好的选择,但数组的长度需提前指定且不可变,如果我们需要保存一个动态增长的数据(其数量不确定),Java集合类可以很好实现。

集合类又称为容器类。所有的集合类都位于 java.util 包下,为了处理多线程环境下的并发安全问题,在 java.util.concurrent 包下提供了一些多线程支持的集合类。

Java集合类可分为两大类:

1)Collection :

  • 1.1)List必须保持元素特定的顺序
  • 1.2)Set不能有重复元素
  • 1.3)Queue保持一个队列(先进先出)的顺序

2)Map :

  • 保存的是一组 “键值对” 对象 (key-value对)

 

【虚线箭头表示实现关系,实线箭头表示继承关系】

二. Java集合类的层次关系

1. Iterable<T> 接口

java.lang 下的 Interface Iterable<T> 迭代器接口,是Collecton接口的父接口,包括

  • default void forEach() 方法
  • Iterator<T> iterator() 方法  【Iterator<T> 是java.util 下的接口】
实现这个Iterable接口的对象允许使用foreach进行遍历,所以,所有的Collection集合对象都具有"foreach可遍历性"。

2. Collection 接口

1)Set 接口,继承自Collection 接口。“丢进”Set集合里的多个对象之间没有明显的顺序,不能包含重复元素。【元素特点:无序,不重复】

      注:Set判断两个元素是否相同是用equals(object)方法,相同返回true,不同返回false,Set会接受该新元素,而不是用“==”运算符。因此,Set的实现类应实现一个有效的equals(object)方法;

  • HashSet :允许使用null元素,基于HashMap实现;【非线程安全】

HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和查找性能。

当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值决定该对象在HashSet中的存储位置。

注:HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法的返回值相等


  • LinkedHashSet:继承自HashSet,允许null元素,LinkedHashSet中有一个LinkedHahsMap(适配器模式),基于双向链表和HashMap实现;【非线程安全】

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


  • TreeSet : 不允许null元素,基于TreeMap 实现,底层是红黑树;【非线程安全】

Treeset有两种排序方式:自然排序和比较器排序。

A)自然排序:默认排序方式,java.lang 下的comparable 接口,实现了int compareTo(T o)方法;

obj1.compareTo(obj2)方法如果返回0,表示两个对象相等;如果返回一个正数,则表明obj1>obj2;如果返回一个负数,则表明obj1<obj2.

如果两个对象的equals方法返回true,则其compareTo方法应该返回0;

B)比较器排序java.util 下的comparator接口,实现了int compare(T o1,T o2)方法,取决于创建TreeSet时所用的构造方法;

TreeSet实现java.io.Serializable的方式。当写入到输出流时,依次写入“比较器、容量、全部元素”;当读出输入流时,再依次读取。

2)List接口List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许加入重复元素,因为它可以通过索引来访问指定位置的集合元素。【元素特点:有序,可重复】

  • ArrayList : 允许null 元素,基于数组实现,它封装了一个动态的增长的、允许再分配的Object[]数组。【非线程安全】

  • LinkedList : 允许null元素,基于双端链表实现,可用作队列和栈;Deque接口继承自Queue接口。【非线程安全】

  • Stack,继承自Vector,用于模拟“栈”先进后出;【线程安全】

3)Queue接口

用于模拟"队列"这种数据结构(先进先出 FIFO)。队列的头部保存着队列中存放时间最长的元素,队列的尾部保存着队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素,队列不允许随机访问队列中的元素。

  • PriorityQueue : 不允许null元素,按照队列元素的大小进行重新排序,底层以二叉堆实现;
  • ArrayDeque : 是一个基于数组的双端队列,和ArrayList类似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素
  • LinkedList

3. Map 接口

Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value。key和value都可以是任何引用类型的数据。Map 的key不能重复,允许null值,value可重复,允许null值;
  • HashMap : jdk1.7与jdk1.8的底层实现原理有差别,jdk1.7 :散列表+链表 ;jdk1.8: 散列表+链表+红黑树 【非线程安全】

两个key通过equals()方法比较返回true,同时两个key的hashCode值也必须相等。

  • LinkedHashMap : 继承自HashMap, 底层是双向链表+HashMap 【非线程安全】

  • TreeMap :实现了SortedMap<K,V>接口,该接口继承自Map接口,底层实现是红黑树【非线程安全】
TreeMap就是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点。TreeMap存储key-value对(节点)时,需要根据key对节点进行排序。TreeMap可以保证所有的key-value对处于有序状态。同样,TreeMap也有两种排序方式: 自然排序、定制排序。
  • Hashtable :【线程安全】

 

三、集合类的使用场景

  1.Set集合类的应用场景(HashSet、LinkedHashSet、TreeSet)

1)HashSet的性能总是比TreeSet好,因为TreeSet需要额外的红黑树算法来维护集合元素的次序。只有当需要一个保持排序的Set时,才应该使用TreeSet,否则都应该使用HashSet。

2)对于普通的插入、删除操作,LinkedHashSet比HashSet要略慢一点,这是由维护链表所带来的开销造成的。不过,因为有了链表的存在,遍历LinkedHashSet会更快。

3)EnumSet是所有Set实现类中性能最好的,但它只能保存同一个枚举类的枚举值作为集合元素。

4)HashSet、TreeSet、EnumSet都是"线程不安全"的,通常可以通过Collections工具类的synchronizedSortedSet方法来"包装"该Set集合。

Set s = Collections.synchronizedSet(new HashSet<>());

或SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));2.List 集合类的应用场景(ArrayList 、LinkedList)1)java提供的List就是一个"线性表接口",ArrayList(基于数组的线性表)、LinkedList(基于链表的线性表)是线性表的两种典型实现。2)Queue代表了队列,Deque代表了双端队列(既可以作为队列使用、也可以作为栈使用)3)内部以链表作为底层实现的集合在执行插入、删除操作时有很好的性能4)因为数组以一块连续内存来保存所有的数组元素,所以数组在随机访问时性能最好。所以的内部以数组作为底层实现的集合在随机访问时性能最好。
3.Map集合类的应用场景(HashMap 、 linkedHashMap、TreeMap)
1)HashMap和Hashtable的效率大致相同,因为它们的实现机制几乎完全一样。但HashMap通常比Hashtable要快一点,因为Hashtable需要额外的线程同步控制。
2) TreeMap通常比HashMap、Hashtable要慢(尤其是在插入、删除key-value对时更慢),因为TreeMap底层采用红黑树来管理key-value对。
3) 使用TreeMap的一个好处就是: TreeMap中的key-value对总是处于有序状态,无须专门进行排序操作。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!