数据结构

Java Collections框架

Java Collections框架包含大量集合接口以及这些接口的实现类,和操作他们的算法(如排序/查找/反转/替换/复制/取最小元素/取最大元素等)。
Java Collections框架包括 List(列表)、Set(集合)、Map(映射表)、Queue(队列)、Stack(栈) 等数据结构。
其中 List/Queue/Set/Stack 都继承自Collection接口。

List

  1. 有序容器,保持了每个元素的进入顺序,输出的顺序就是插入的顺序。因为按对象进入的顺序保存对象,故能对列表中每个元素的插入和删除位置进行精确的控制。
  2. 允许重复的对象。可以插入多个null元素。

Set

  1. 无序容器,你无法保证每个元素的存储顺序,但TreeSet实现了SortedSet接口,因此TreeSet容器中的元素是有序的。
  2. 不允许重复对象,故存入Set的每个元素都必须定义equals()方法来确保对象的唯一性。只允许一个 null 元素。
  3. Set接口最流行的几个实现类是 HashSet、TreeSet以及 LinkedHashSet 。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。

Map

  1. Map不是collection的子接口或者实现类。Map是一个接口。
  2. Map的每个Entry都持有两个对象,也就是一个键一个值,Map可能会持有相同的值对象但键对象必须是唯一的。
  3. Map里你可以拥有随意个null值但最多只能有一个null键。

什么场景下使用list/set/map?

  • 如果你经常会使用索引来对容器中的元素进行访问,那么List是你的正确的选择。如果你已经知道索引了的话,那么List的实现类比如 ArrayList可以提供更快速的访问,如果经常添加删除元素的,那么肯定要选择LinkedList。
  • 如果你想容器中的元素能够按照它们插入的次序进行有序存储,那么还是List,因为List是一个有序容器,它按照插入顺序进行存储。
    如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个Set的实现类,比如HashSet、TreeSet或者LinkedHashSet。如果插入的元素唯一且有序可以使用TreeSet,TreeSet中的元素可以使用Java里的Comparator或者Comparable进行排序。
  • 如果你以键和值的形式进行数据存储那么Map是你正确的选择。

List的实现类:ArrayList/Vector/LinkedList

这三个类在java.util包中。

ArrayList和Vector为可伸缩数组(即可以动态改变长度的数组)。基于数组实现的列表。他们会在内存中开辟一块连续的空间来存储数据,故支持用下标访问元素,同时索引数据的速度比较快。但是插入元素时需要移动数组中的元素,所以对数据的插入操作执行地比较慢。

ArrayList和Vector都有一个初始化的容量大小,当数组中存储的元素超过这个大小时,就需要扩充他们的存储空间。为了提高程序的效率,每次扩充容量会一次增加多个存储单元,而不是一个存储单元。ArrayList默认扩充为原来的1.5倍(没有提供方法来设置空间扩充的方法),Vector默认扩充为原来的2倍(每次扩充空间的大小是可以设置的)。

ArrayList中没有一个方法是同步的(synchronization),Vector的绝大多数方法(add/insert/remove/set/equals/hashcode等)都是直接或者间接同步的,所以Vector是线程安全的,ArrayList不是线程安全的。故Vector性能略逊于ArrayList。

LinkedList是基于双向链表实现的。对数据的索引需要从列表头开始遍历,因此索引数据的速度较慢。但插入元素不需要对数据进行移动,因此插入效率较高。LinkedList是非线程安全的容器。

因此,当对数据的主要操作为索引或只在集合的末端增加、删除元素时,使用ArrayList或Vector效率比较高;当对数据的操作主要为指定位置的插入或删除操作时,使用LinkedList效率比较高;当在多线程中使用时(即多个线程会同时访问该容器),选用Vector较为安全。

Map的实现类:HashMap/Hashtable/TreeMap/LinkedHashMap/WeakHashMap

java.util.Map

在List中通过下标来对其内容进行索引。在Map中通过对象(key)对其内容(value)进行索引。

HashMap继承AbstractMap同时实现Map
Hashtable继承Dictionary同时实现Map
TreeMap继承AbstractMap同时间接实现SortedMap
LinkedHashMap继承HashMap同时实现Map
WeakHashMap继承AbstractMap同时实现Map

HashMap和Hashtable的区别

  1. HashMap最多允许一个空键(key为null),Hashtable不允许。
  2. HashMap非线程安全,Hashtable线程安全。故HashMap性能略高。
  3. HashMap的hash数组默认大小是16,且一定是2的指数。Hashtable的hash数组默认大小是11,增加的方式是old * 2 + 1。
  4. HashMap使用Iterator迭代器获取对象。Hashtable使用Enumeration获取集合(容器)中的对象。
    Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)集合中的元素。
  5. HashMap使用containsKey和contatinsValue。Hashtable使用contains。

TreeMap和LinkedHashMap
HashMap里面存入的键值对在取出时没有固定的顺序,是随机的。
TreeMap实现了SortMap接口,可以把它保存的键值对根据key排序。因此,如果需要按自然顺序或自定义顺序遍历key,则TreeMap好用。
LinkedHashMap是HashMap的一个子类,如果需要输出的顺序和输入的顺序相同,则LinkedHashMap好用。

WeakHashMap
WeakHashMap与HashMap类似,二者不同在于WeakHashMap中key采用的是弱引用的方式,只要key不再被外部引用,他就可以被GC回收。
而HashMap中key采用强引用的方式,当key没有外部引用时,只有这个key从HashMap中删除后,才可以被GC回收。

Map注意事项

  1. Hashtable的线程安全指什么?
    线程安全(同步)指在一个时间点,只能有一个线程可以修改hash表,任何线程在执行Hashtable的更新操作前都需要获取对象锁。
  2. 如何实现HashMap的同步?
    通过如下方式:
    Map map = Collections.synchronizedMap(new HashMap())
    该方法返回一个同步的HashMap,该HashMap封装了底层的所有方法来保证该HashMap线程安全。
  3. 为什么HashMap可以存为null的key?
    这是因为HashMap对null进行了特殊处理,将null的hashCode值定为了0,从而将其存放在哈希表的第0个存储空间(bucket)。

数组和链表

数组

  1. 数组是连续的内存空间。
  2. 数组必须事先定义固定的长度。
  3. 数组无需初始化,因为数组的元素在内存的栈区,系统自动申请空间,即静态分配内存。
  4. 访问数据,可以通过下标读取,时间复杂度O(1),随机访问性强。
  5. 添加删除数据需要移动操作数据所在位置后的所有数据,时间复杂度O(N)。

链表

  1. 链表是非连续的内存空间。
  2. 链表的结点元素在内存的堆区,每个元素须手动申请空间,如malloc。堆操作灵活性更强(添加删除数据)。堆中分配空间,自由度大但申请管理比较麻烦。
  3. 访问数据,需要从头遍历整个链表直到找到要访问的数据,随机访问性弱。时间复杂度O(N)。
  4. 添加删除数据只需要知道操作位置的指针。时间复杂度O(1)。

线性表

线性表:零个或多个数据元素的有限序列。
注:序列是指元素之间是有顺序的。
线性表包括:

  1. 顺序存储结构的线性表
  2. 链式存储结构的线性表(单向链表/双向链表/循环链表)
    栈:
    用顺序线性表实现(可用两栈共享空间)
    用链式线性表实现
    队列:
    用顺序线性表实现(可用循环队列)
    用链式线性表实现

栈和队列是线性表的一种。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值