数据结构:ArrayList、Vector、LinkedList和HashMap、HashTable、LinkedHashMap、TreeMap

一、ArrayList、Vector、LinkedList

ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,二者都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快,插入数据慢;Vector由于使用了synchronized方法(如add、insert、remove、set、equals、hashcode等操作),因此是线程安全,性能上比ArrayList要差。
LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快!LinkedList双向链表,是指可以从first依次遍历至last(从头到尾),也可以从last遍历至first(从尾到头),但首尾没有构成环,不同于双向循环链表(注意区分)。

ArrayList和LinkedList的大致区别:
    1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
    2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
    3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
    
ArrayList和LinkedList在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。

2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。

3.LinkedList不支持高效的随机元素访问。

4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。

二、HashMap、HashTable、LinkedHashMap和TreeMap

Java为数据结构中的映射定义了一个接口java.util.Map,它有四个实现类,分别是HashMap、HashTable、LinkedHashMap和TreeMap。


Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复。 Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。注意,如果在映射中重新插入 键,则插入顺序不受影响。(如果在调用 m.put(k, v) 前 m.containsKey(k) 返回了 true,则调用时会将键 k 重新插入到映射 m 中。)

HashMap是一个最常用的Map,它根据键的 HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。

Hashtable与HashMap类似,它继承自Dictionary类,不同的是:它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。

LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序;LinkedHashMap 是比 HashMap 多了一个链表的结构。与 HashMap 相比 LinkedHashMap 维护的是一个具有双重链表的HashMap,LinkedHashMap支持两种排序,一种是插入排序,一种是使用排序,最近使用的会移至尾部例如 M1 M2 M3 M4,使用M3后为 M1 M2 M4 M3了,LinkedHashMap 输出时其元素是有顺序的,而 HashMap 输出时是随机的,如果 Map 映射比较复杂而又要求高效率的话,最好使用 LinkedHashMap,但是多线程访问的话可能会造成不同步,所以要用 Collections.synchronizedMap 来包装一下,从而实现同步。

TreeMap不仅可以保持顺序,而且可以用于排序(TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器。)。TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap的键和值都不能为空。

一般情况下,我们用的最多的是HashMap,在Map 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。如果需要输出的顺序和输入的相同,那么用LinkedHashMap 可以实现,它还可以按读取顺序来排列。LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢,有HashMap的全部特性。


Collator 类执行区分语言环境的 String 比较。使用此类可为自然语言文本构建搜索和排序例程。
Collator 是一个抽象基类,如果正好比较 String 一次,则 compare 方法可提供最佳性能。 但在对 String 列表排序时,通常需要对每个 String 进行多次比较。
在这种情况下,CollationKey 可提供更好的性能。CollationKey 类将一个 String 转换成一系列可与其他 CollationKey 进行按位比较的位。
CollationKey 是由 Collator 对象为给定的 String 所创建的。
不能直接创建 CollationKey。而是通过调用 Collator.getCollationKey 来生成。
只能比较同一个 Collator 对象生成的 CollationKey。
CollationKey 表示遵守特定 Collator 对象规则的 String。
比较两个 CollationKey 将返回它们所表示的 String 的相对顺序。
使用 CollationKey 来比较 String 通常比使用 Collator.compare 更快。
因此,当必须多次比较 String 时(例如,对一个 String 列表进行排序),
使用 CollationKey 会更高效。

遍历Map有两种方法:
 (1)map的keySet()方法获得键的集合,再调用键集合的iterator方法获得键的迭代器,以此迭代地取出Map中的键,用get方法获得键对应的值,便完成了Map的遍历。代码如下所示:
 //使用迭代器遍历Map的键,根据键取值
         Iterator it = map.keySet().iterator();
         while (it.hasNext()){
            key = it.next();
            value = map.get(key);
            System.out.println("key: " + key + "; value: " + value );
         }


 (2)使用Map的entrySet方法获得Map中记录的集合,每条对象都是一个Map.Entry对象,使用其getKey方法获得记录的键,使用其getValue方法获得记录的值。代码如下所示:
       
 //或者使用迭代器遍历Map的记录Map.Entry
         Map.Entry entry = null;
         it = map.entrySet().iterator();
         while (it.hasNext()){
            //一个Map.Entry代表一条记录
            entry = (Map.Entry)it.next();
            //通过entry可以获得记录的键和值
            //System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue()); 


您的回应...

相关话题

查看全部

也许你感兴趣

换一批

热门标签

更多