Android 常用数据结构总结

数据结构

Android 常用数据结构总结

Android 常用数据结构总结

数组:

优点:查询快,如果知道索引可以快速存取

缺点:删除慢,大小固定

有序数组:

优点:比无序数组查找块

缺点:删除和插入慢,大小固定

栈:

优点:提供后进先出的存取方式

缺点:存取其他项很慢

队列:

优点:提供先进先出的存取方式

缺点:存取其他项都很慢

链表(单链表、循环链表、双向链表

Android 常用数据结构总结

优点:插入快,删除快

缺点:查找慢(一个个节点查)

二叉树

Android 常用数据结构总结

优点:查找、插入、删除都快(平衡二叉树)

缺点:删除算法复杂

红黑树

Android 常用数据结构总结

 

优点:查找,插入,删除都快,树总是平衡的(局部调整)

缺点:算法复杂

2-3-4树

优点:查找,插入,删除都快,树总是平衡的。类似的树对磁盘存储有用,

缺点:算法复杂

哈希表

Android 常用数据结构总结

 

优点:如果关键字已知则存取速度极快,插入快

缺点:删除慢,如果不知道关键字则存取很慢,对存储空间使用不补充

优点:插入、删除快、对最大数据的项存取很快

缺点:对其他数据项存取很慢

优点:对现实世界建模

缺点:有些算法慢且复杂

常用集合类的继承结构如下:

Collection<--List<--Vector 

Collection<--List<--ArrayList 

Collection<--List<--LinkedList 

Collection<--Set<--HashSet 

Collection<--Set<--HashSet<--LinkedHashSet 

Collection<--Set<--SortedSet<--TreeSet 

Map<--SortedMap<--TreeMap 

Map<--HashMap (补充一个HashMap的子类LinkedHashMap:)

注意这里的 Collection、List、Set和Map都是接口(Interface)

List

List是有序的Collection,使用此接口能够精确地控制每个元素插入的位置。类似于JAVA的数组

Vector

基于数组(array)的list,ArrayList其实是对数组的动态扩充,底层的数据结构使用的是数组结构(数组长度是可变的百分之百延长):

特点:vector是线程同步的(sychronized)的,在add(), remove(), get()等方法中都加了同步,线程安全的。速度相对ArrayList慢些。

ArrayList

基于数组(array)的list,ArrayList其实是对数组的动态扩充,底层的数据结构使用的是数组结构(数组长度是可变的百分之五十延长):

特点:查询很快,但增删较慢,线程不同步。性能上要比vector好一些,但是线程不安全。

Linkedlist

Linkedlist不同于前两个,基于单链表实现的。它的每一个节点(node)都包含两方面的内容:1,节点本身的数据(data);2,下一个节点的信息(nextnode)。所以当对Linkedlist做添加,删除动作的时候就不用像基于数组的ArrayList一样,必须进行大量的数据移动。只要更改nextnode的相关信息就可以实现了,这是Linkedlist的优势

LinkedList根据序号获取数据,是二分进行遍历,如果序号小于总长度的一半,就从链表头部开始往后遍历,直到找到对应的序号。如果序号大于总长度的一半,就从链表尾部往前进行遍历,直到找到对应的序号。拿到数据。

List总结:

所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]

所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]

所有的List中可以有null元素,例如[ tom,null,1 ]

基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操作

Set: 

Set是一种不包含重复的元素的无序Collection。 

HashSet: 

虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。

HashSet是根据hashCode来决定存储位置的,是通过HashMap实现的,所以对象必须实现hashCode()方法,存储的数据无序不能重复,可以存储null,但是只能存一个。

但是Set则是在 HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。

看看 HashSet的add(Object obj)方法的实现就可以一目了然了。 

Java代码 

public boolean add(Object obj) {   

   return map.put(obj, PRESENT) == null;   

}     

这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。 

LinkedHashSet: 

HashSet的一个子类,一个链表。 

TreeSet: 

SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。

TreeSet是根据二叉树实现的,也就是TreeMap, 放入数据不能重复且不能为null,可以重写compareTo()方法来确定元素大小,从而进行升序排序。 

Set总结: 

Set实现的基础是Map(HashMap)

Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

Map下面的概念和特性 

Map 是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个 Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求,你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。

Map有两种比较常用的实现:HashMap和TreeMap。

HashMap

HashMap也用到了哈希码的算法,以便快速查找;HashMap是基于散列链表来实现的,简单的来说,根据key算出一个hash值,确定一个存放index,但是hash值有可能会冲突重复,所以如果冲突的hash值就需要以链表的形式在同一个index存放了。可以参考:http://blog.****.net/u011060103/article/details/51355763

 LinkedHashMap继承自HashMap,特点是内部存入数据是有顺序的,增加了记住元素插入或者访问顺序的功能,这个是通过内部一个双向的循环链表实现的。与 HashMap 一样,它可以为基本操作(add、contains 和 remove)提供稳定的性能,假定哈希函数将元素正确分布到桶中。由于增加了维护链接列表的开支,其性能很可能比 HashMap 稍逊一筹,不过这一点例外:LinkedHashMap 的 collection 视图迭代所需时间与映射的大小 成比例。HashMap 迭代时间很可能开支较大,因为它所需要的时间与其容量 成比例。

TreeMap

TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。 键和值的关联很简单,用put(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。

TreeMap是有序的,通过comparator接口我们可以对TreeMap的内部排序进行精密的控制

TreeMap的使用大致跟HashMap类似,但是内部实现是根据红黑树来实现的。红黑树是一种平衡有序的二叉树,具有二叉树所有的特性,TreeMap的插入删除查询都是依据红黑树的规则来进行的。可以参考:http://blog.****.net/chenssy/article/details/26668941

Hashtable

先说下,HashMap和TreeMap都是线程不安全的,多线程操作的时候可能会造成数据错误。Hashtable是线程安全的。其他内部实现,与HashMap都是一样的。

几个常用类的区别 

1.ArrayList: 元素单个,效率高,多用于查询 

2.Vector: 元素单个,线程安全,多用于查询 

3.LinkedList:元素单个,多用于插入和删除 

4.HashMap: 元素成对,元素可为空 

5.HashTable: 元素成对,线程安全,元素不可为空 

6. HashSet:元素单个,元素不可重复

Vector、ArrayList和LinkedList 

大多数情况下,从性能上来说ArrayList最好,但是当集合内的元素需要频繁插入、删除时LinkedList会有比较好的表现,但是它们三个性能都比不上数组,另外Vector是线程同步的。所以: 如果能用数组的时候(元素类型固定,数组长度固定),请尽量使用数组来代替List; 如果没有频繁的删除插入操作,又不用考虑多线程问题,优先选择ArrayList; 如果在多线程条件下使用,可以考虑Vector; 如果需要频繁地删除插入,LinkedList就有了用武之地:如果你什么都不知道,用ArrayList没错。

https://blog.****.net/column/details/13066.html