没有最好的,只有最合适的。
目录
摘要
在你有一定技术能力上,如果哪天处理数据你发现你正在使用的方法对于要解决的问题效率不高,可能是因为你使用了错误的数据结构。
- 数组/数组列表:可以使用索引很方便的访问到指定位置的数据,但有一个重大的缺陷就是在数组中间添加或删除一个元素开销很大。
- 链表:而对于链表而言能在很大程度减小这个开销,但是它失去了快速随机访问,哪怕使用get(index)方法,依旧是进行遍历访问。
- 散列集:链表和数组允许我们指定元素的次序,但是当我们想查看某个元素却又不记得它的位置就需要访问所有元素直到找到为止,如果不在意元素的顺序,有几种可以能够快速查询元素的数据结构,缺点是无法控制元素出现的次序,例如散列表。
- 树集:TreeSet类相比散列集有所改进,它是一个有序集合。可以以任意顺序插入元素,在对集合遍历时,值将自动地按照排序后的顺序呈现。而且,与检查数组或链表中的重复元素相比,使用树会快很多。当然,将一个元素添加到树中要比添加到散列表中慢,而且要使用树集,必须能够比较元素。
- 映射:上面所说的,集是一个集合,允许快速查找现有的元素,但是通常情况下我们会知道某些关键信息,希望去查找与之关联的元素。映射便是为此设计,它用来存放键值对,也是我们很熟悉的结构。
一、数组
1.1 数组的缺点
在我们程序日常应用中,有很多地方都用到了数组以及动态的ArrayList,但是他们有一个很大的缺陷,就是从数组中间删除一个元素需要付出很大的代价,原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动, 在数组中间的位置上插入一个元素也是一样的道理。
二、链表
2.1 链表中间元素的删除原理
而另外一个数据结构——链表就可以解决这个问题。数组是在连续的存储位置上存放对象引用,而链表则是将每个对象存放在单独的链接中。在Java中,所有的链表都是双向链接,每个链接中还存放着指向前驱的引用。
从链表中删除一个元素很简单,只需要将这个元素相邻的两个元素链接起来,将要删除的元素从链接中剔除即可。例如链表中分别有A、B、C三个链接,如果要删除B,只需要将A指向B的引用替换成A指向C的引用;将C指向B的引用替换成C指向A的引用。插入也是相同的道理。
2.2 链表的简单使用
链表是一个有序集合,每个对象的位置十分重要。LinkedList类中的add方法可以将对象添加到链表的尾部。但是我们之所以使用链表的一大原因就是需要将元素添加到链表的中间,而这种依赖于位置的add方法将有迭代器负责,下面是链表具体使用的两个简单小例子。
链表的简单使用1:先添加3个元素,再删除第二个元素
public static void main(String[] args) {
LinkedList<String> students = new LinkedList<String>();
students.add("Xiao Ming");
students.add("Xiao Hong");
students.add("Xiao Hua");
Iterator<String> iter = students.iterator();
String first = iter.next();
System.out.println("first:" + first); //first:Xiao Ming
String second = iter.next();
System.out.println("second:" + second); //second:Xiao Hong
iter.remove