Java基础之容器综述篇

来源:互联网 发布:傲剑弓箭升级数据大全 编辑:程序博客网 时间:2024/06/14 07:58

Java基础之容器综述篇

总体框架

Java集合是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。Java集合工具包位置是java.util.*
Java集合主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)。

Java集合工具包框架图(如下):

这里写图片描述

看上面的框架图,先抓住它的主干,即Collection和Map。

  1. Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性。

    • Collection包含了List和Set两大分支。

      1. List是一个有序的队列,每一个元素都有它的索引。第一个元素的索引值是0。List的实现类有LinkedList, ArrayList, Vector, Stack。

      2. Set是一个不允许有重复元素的集合。Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。

  2. Map是一个映射接口,即key-value键值对。Map中的每一个元素包含“一个key”和“key对应的value”。
    AbstractMap是个抽象类,它实现了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是继承于AbstractMap。
    Hashtable虽然继承于Dictionary,但它实现了Map接口。

接下来,再看Iterator。它是遍历集合的工具,即我们通常通过Iterator迭代器来遍历集合。我们说Collection依赖于Iterator,是因为Collection的实现类都要实现iterator()函数,返回一个Iterator对象。
ListIterator是专门为遍历List而存在的。

再看Enumeration,它是JDK 1.0引入的抽象类。作用和Iterator一样,也是遍历集合;但是Enumeration的功能要比Iterator少。在上面的框图中,Enumeration只能在Hashtable, Vector, Stack中使用。

最后,看Arrays和Collections。它们是操作数组、集合的两个工具类。

Collection架构

概要

主要有List,Set,Queue三个子接口

这里写图片描述

AbstractList继承自AbstractCollection,实现了List接口
AbstractList继承自AbstractCollection,实现了set接口

Collection是一个接口,它主要的两个分支是:List 和 Set。

List和Set都是接口,它们继承于Collection。List是有序的队列,List中可以有重复的元素;而Set是数学概念中的集合,Set中没有重复元素!

List和Set都有它们各自的实现类。

为了方便,我们抽象出了AbstractCollection抽象类,它实现了Collection中的绝大部分函数;这样,在Collection的实现类中,我们就可以通过继承AbstractCollection省去重复编码。AbstractList和AbstractSet都继承于AbstractCollection,具体的List实现类继承于AbstractList,而Set的实现类则继承于AbstractSet。

另外,Collection中有一个iterator()函数,它的作用是返回一个Iterator接口。通常,我们通过Iterator迭代器来遍历集合。ListIterator是List接口所特有的,在List接口中,通过ListIterator()返回一个ListIterator对象。

Collection简介

Collection的定义如下:

public interface Collection<E> extends Iterable<E>

它是一个接口,是高度抽象出来的集合,它包含了集合的基本操作:添加、删除、清空、遍历(读取)、是否为空、获取大小、是否保护某元素等等。

Collection接口的所有子类(直接子类和间接子类)都必须实现2种构造函数:不带参数的构造函数 和 参数为Collection的构造函数。带参数的构造函数,可以用来转换Collection的类型

主要方法:

// Collection的APIabstract boolean         add(E object)abstract boolean         addAll(Collection<? extends E> collection)abstract void            clear()abstract boolean         contains(Object object)abstract boolean         containsAll(Collection<?> collection)abstract boolean         equals(Object object)abstract int             hashCode()abstract boolean         isEmpty()abstract Iterator<E>     iterator()abstract boolean         remove(Object object)abstract boolean         removeAll(Collection<?> collection)abstract boolean         retainAll(Collection<?> collection)abstract int             size()abstract <T> T[]         toArray(T[] array)abstract Object[]        toArray()

List简介

List的定义如下:

public interface List<E> extends Collection<E> {}

List是一个继承于Collection的接口,即List是集合中的一种。List是有序的队列,List中的每一个元素都有一个索引;第一个元素的索引值是0,往后的元素的索引值依次+1。和Set不同,List中允许有重复的元素。

List的官方介绍如下:

A List is a collection which maintains an ordering for its elements. Every element in the List has an index. Each element can thus be accessed by its index, with the first index being zero. Normally, Lists allow duplicate elements, as compared to Sets, where elements have to be unique.

关于API方面。既然List是继承于Collection接口,它自然就包含了Collection中的全部函数接口;由于List是有序队列,它也额外的有自己的API接口。主要有“添加、删除、获取、修改指定位置的元素”、“获取List中的子队列”等。

// Collection的APIabstract boolean         add(E object)abstract boolean         addAll(Collection<? extends E> collection)abstract void            clear()abstract boolean         contains(Object object)abstract boolean         containsAll(Collection<?> collection)abstract boolean         equals(Object object)abstract int             hashCode()abstract boolean         isEmpty()abstract Iterator<E>     iterator()abstract boolean         remove(Object object)abstract boolean         removeAll(Collection<?> collection)abstract boolean         retainAll(Collection<?> collection)abstract int             size()abstract <T> T[]         toArray(T[] array)abstract Object[]        toArray()// 相比与Collection,List新增的API:abstract void                add(int location, E object)abstract boolean             addAll(int location, Collection<? extends E> collection)abstract E                   get(int location)abstract int                 indexOf(Object object)abstract int                 lastIndexOf(Object object)abstract ListIterator<E>     listIterator(int location)abstract ListIterator<E>     listIterator()abstract E                   remove(int location)abstract E                   set(int location, E object)abstract List<E>             subList(int start, int end)

List接口为Collection直接接口。

List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。

一个有序的Collection(也称序列),元素可以重复
有顺序所以操作时可以在方法中使用索引

实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

ArrayList

ArrayList是一个动态数组,也是我们最常用的集合。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。随着容器中的元素不断增加,容器的大小也会随着增加。在每次向容器中增加元素的同时都会进行容量检查,当快溢出时,就会进行扩容操作。所以如果我们明确所插入元素的多少,最好指定一个初始容量值,避免过多的进行扩容操作而浪费时间、效率。

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。

add 操作以分摊的固定时间运行,也就是说,添加 n 个元素需要 O(n) 时间(由于要考虑到扩容,所以这不只是添加元素会带来分摊固定时间开销那样简单)。

ArrayList擅长于随机访问。同时ArrayList是非同步的。

LinkedList

同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。

所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。

由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。

与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(…));

Vector

与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

Stack

Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

Set简介

前面,我们已经系统的对List和Map进行了学习。接下来,我们开始可以学习Set。相信经过Map的了解之后,学习Set会容易很多。毕竟,Set的实现类都是基于Map来实现的(HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的)。

首先,我们看看Set架构。
这里写图片描述

  1. Set 是继承于Collection的接口。它是一个不允许有重复元素的集合。

  2. AbstractSet 是一个抽象类,它继承于AbstractCollection,AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利。

  3. HastSet 和 TreeSet 是Set的两个实现类。

    • HashSet依赖于HashMap,它实际上是通过HashMap实现的。HashSet中的元素是无序的。
    • TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。TreeSet中的元素是有序的。

Set的定义如下:

public interface Set<E> extends Collection<E> {}

Set是一个继承于Collection的接口,即Set也是集合中的一种。Set是没有重复元素的集合。

无顺序不可以重复,无序因而不能通过索引操作对象

通常set不会包含成对的元素

set接口没有定义特别的方法

它维持它自己的内部排序,所以随机访问没有任何意义

关于API方面。Set的API和Collection完全一样。

// Set的APIabstract boolean         add(E object)abstract boolean         addAll(Collection<? extends E> collection)abstract void             clear()abstract boolean         contains(Object object)abstract boolean         containsAll(Collection<?> collection)abstract boolean         equals(Object object)abstract int             hashCode()abstract boolean         isEmpty()abstract Iterator<E>     iterator()abstract boolean         remove(Object object)abstract boolean         removeAll(Collection<?> collection)abstract boolean         retainAll(Collection<?> collection)abstract int             size()abstract <T> T[]         toArray(T[] array)abstract Object[]         toArray()

Set接口下具体的实现类有:TreeSet,HashSet,LinkedHashSet,SortedSet,EnumSet

EnumSet

是枚举的专用Set。所有的元素都是枚举类型。

HashSet

HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。

TreeSet

基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

AbstractCollection

AbstractCollection的定义如下:

public abstract class AbstractCollection<E> implements Collection<E> {}

AbstractCollection是一个抽象类,它实现了Collection中除iterator()和size()之外的函数。

AbstractCollection的主要作用:它实现了Collection接口中的大部分函数。从而方便其它类实现Collection,比如ArrayList、LinkedList等,它们这些类想要实现Collection接口,通过继承AbstractCollection就已经实现了大部分的接口了。

AbstractList

AbstractList的定义如下:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}

AbstractList是一个继承于AbstractCollection,并且实现List接口的抽象类。它实现了List中除size()、get(int location)之外的函数。

AbstractList的主要作用:它实现了List接口中的大部分函数。从而方便其它类继承List。

另外,和AbstractCollection相比,AbstractList抽象类中,实现了iterator()接口。

AbstractSet

AbstractSet的定义如下:

public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}

AbstractSet是一个继承于AbstractCollection,并且实现Set接口的抽象类。由于Set接口和Collection接口中的API完全一样,Set也就没有自己单独的API。和AbstractCollection一样,它实现了List中除iterator()和size()之外的函数。

AbstractSet的主要作用:它实现了Set接口中的大部分函数。从而方便其它类实现Set接口。

Iterator

Iterator的定义如下:

public interface Iterator<E> {}

Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口,包括:是否存在下一个元素、获取下一个元素、删除当前元素。

注意:Iterator遍历Collection时,是fail-fast机制的。即,当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。关于fail-fast的详细内容,我们会在后面专门进行说明。TODO

// Iterator的APIabstract boolean hasNext()abstract E next()abstract void remove()

ListIterator

ListIterator的定义如下:

public interface ListIterator<E> extends Iterator<E> {}

ListIterator是一个继承于Iterator的接口,它是队列迭代器。专门用于便利List,能提供向前/向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等等API接口。

// ListIterator的API// 继承于Iterator的接口abstract boolean hasNext()abstract E next()abstract void remove()// 新增API接口abstract void add(E object)abstract boolean hasPrevious()abstract int nextIndex()abstract E previous()abstract int previousIndex()abstract void set(E object)

Map架构

概要

前面,我们已经系统的对List进行了学习。接下来,我们先学习Map,然后再学习Set;因为Set的实现类都是基于Map来实现的(如,HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的)。

首先,我们看看Map架构。
这里写图片描述

如上图:

  1. Map 是映射接口,Map中存储的内容是键值对(key-value)。
  2. AbstractMap 是继承于Map的抽象类,它实现了Map中的大部分API。其它Map的实现类可以通过继承AbstractMap来减少重复编码。
  3. SortedMap 是继承于Map的接口。SortedMap中的内容是排序的键值对,排序的方法是通过比较器(Comparator)。
  4. NavigableMap 是继承于SortedMap的接口。相比于SortedMap,NavigableMap有一系列的导航方法;如”获取大于/等于某对象的键值对”、“获取小于/等于某对象的键值对”等等。
  5. TreeMap 继承于AbstractMap,且实现了NavigableMap接口;因此,TreeMap中的内容是“有序的键值对”!
  6. HashMap 继承于AbstractMap,但没实现NavigableMap接口;因此,HashMap的内容是“键值对,但不保证次序”!
  7. Hashtable 虽然不是继承于AbstractMap,但它继承于Dictionary(Dictionary也是键值对的接口),而且也实现Map接口;因此,Hashtable的内容也是“键值对,也不保证次序”。但和HashMap相比,Hashtable是线程安全的,而且它支持通过Enumeration去遍历。
  8. WeakHashMap 继承于AbstractMap。它和HashMap的键类型不同,WeakHashMap的键是“弱键”。

1 Map

Map的定义如下

public interface Map<K,V> { }

Map 是一个键值对(key-value)映射接口。Map映射中不能包含重复的键;每个键最多只能映射到一个值。

Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。

Map 映射顺序。有些实现类,可以明确保证其顺序,如 TreeMap;另一些映射实现则不保证顺序,如 HashMap 类。

Map 的实现类应该提供2个“标准的”构造方法:第一个,void(无参数)构造方法,用于创建空映射;第二个,带有单个 Map 类型参数的构造方法,用于创建一个与其参数具有相同键-值映射关系的新映射。实际上,后一个构造方法允许用户复制任意映射,生成所需类的一个等价映射。尽管无法强制执行此建议(因为接口不能包含构造方法),但是 JDK 中所有通用的映射实现都遵从它。

Map的API

abstract void                 clear()abstract boolean              containsKey(Object key)abstract boolean              containsValue(Object value)abstract Set<Entry<K, V>>     entrySet()abstract boolean              equals(Object object)abstract V                    get(Object key)abstract int                  hashCode()abstract boolean              isEmpty()abstract Set<K>               keySet()abstract V                    put(K key, V value)abstract void                 putAll(Map<? extends K, ? extends V> map)abstract V                    remove(Object key)abstract int                  size()abstract Collection<V>        values()

说明:
1. Map提供接口分别用于返回 键集、值集或键-值映射关系集。
1. entrySet()用于返回键-值集的Set集合
2. keySet()用于返回键集的Set集合
3. values()用户返回值集的Collection集合
因为Map中不能包含重复的键;每个键最多只能映射到一个值。所以,键-值集、键集都是Set,值集时Collection。
2. Map提供了“键-值对”、“根据键获取值”、“删除键”、“获取容量大小”等方法。

2 Map.Entry

Map.Entry的定义如下:

interface Entry<K,V> { }

Map.Entry是Map中内部的一个接口,Map.Entry是键值对,Map通过 entrySet() 获取Map.Entry的键值对集合,从而通过该集合实现对键值对的操作。

Map.Entry的API

abstract boolean     equals(Object object)abstract K             getKey()abstract V             getValue()abstract int         hashCode()abstract V             setValue(V object)

3 AbstractMap

AbstractMap的定义如下:

public abstract class AbstractMap<K,V> implements Map<K,V> {}

AbstractMap类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作。

要实现不可修改的映射,编程人员只需扩展此类并提供 entrySet 方法的实现即可,该方法将返回映射的映射关系 set 视图。通常,返回的 set 将依次在 AbstractSet 上实现。此 set 不支持 add() 或 remove() 方法,其迭代器也不支持 remove() 方法。

要实现可修改的映射,编程人员必须另外重写此类的 put 方法(否则将抛出 UnsupportedOperationException),entrySet().iterator() 返回的迭代器也必须另外实现其 remove 方法。

AbstractMap的API

abstract Set<Entry<K, V>>     entrySet()         void                 clear()         boolean              containsKey(Object key)         boolean              containsValue(Object value)         boolean              equals(Object object)         V                    get(Object key)         int                  hashCode()         boolean              isEmpty()         Set<K>               keySet()         V                    put(K key, V value)         void                 putAll(Map<? extends K, ? extends V> map)         V                    remove(Object key)         int                  size()         String               toString()         Collection<V>        values()         Object               clone()

4 SortedMap

SortedMap的定义如下:

public interface SortedMap<K,V> extends Map<K,V> { }

SortedMap是一个继承于Map接口的接口。它是一个有序的SortedMap键值映射。

SortedMap的排序方式有两种:自然排序 或者 用户指定比较器。 插入有序 SortedMap 的所有元素都必须实现 Comparable 接口(或者被指定的比较器所接受)。

另外,所有SortedMap 实现类都应该提供 4 个“标准”构造方法:
1. void(无参数)构造方法,它创建一个空的有序映射,按照键的自然顺序进行排序。
2. 带有一个 Comparator 类型参数的构造方法,它创建一个空的有序映射,根据指定的比较器进行排序。
3. 带有一个 Map 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系与参数相同,按照键的自然顺序进行排序。
4. 带有一个 SortedMap 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系和排序方法与输入的有序映射相同。无法保证强制实施此建议,因为接口不能包含构造方法。

SortedMap的API

// 继承于Map的APIabstract void                 clear()abstract boolean              containsKey(Object key)abstract boolean              containsValue(Object value)abstract Set<Entry<K, V>>     entrySet()abstract boolean              equals(Object object)abstract V                    get(Object key)abstract int                  hashCode()abstract boolean              isEmpty()abstract Set<K>               keySet()abstract V                    put(K key, V value)abstract void                 putAll(Map<? extends K, ? extends V> map)abstract V                    remove(Object key)abstract int                  size()abstract Collection<V>        values()// SortedMap新增的API abstract Comparator<? super K>     comparator()abstract K                         firstKey()abstract SortedMap<K, V>           headMap(K endKey)abstract K                         lastKey()abstract SortedMap<K, V>           subMap(K startKey, K endKey)abstract SortedMap<K, V>           tailMap(K startKey)

5 NavigableMap

NavigableMap的定义如下:

public interface NavigableMap<K,V> extends SortedMap<K,V> { }

NavigableMap是继承于SortedMap的接口。它是一个可导航的键-值对集合,具有了为给定搜索目标报告最接近匹配项的导航方法。

NavigableMap分别提供了获取“键”、“键-值对”、“键集”、“键-值对集”的相关方法。

NavigableMap的API

abstract Entry<K, V>             ceilingEntry(K key)abstract Entry<K, V>             firstEntry()abstract Entry<K, V>             floorEntry(K key)abstract Entry<K, V>             higherEntry(K key)abstract Entry<K, V>             lastEntry()abstract Entry<K, V>             lowerEntry(K key)abstract Entry<K, V>             pollFirstEntry()abstract Entry<K, V>             pollLastEntry()abstract K                       ceilingKey(K key)abstract K                       floorKey(K key)abstract K                       higherKey(K key)abstract K                       lowerKey(K key)abstract NavigableSet<K>         descendingKeySet()abstract NavigableSet<K>         navigableKeySet()abstract NavigableMap<K, V>      descendingMap()abstract NavigableMap<K, V>      headMap(K toKey, boolean inclusive)abstract SortedMap<K, V>         headMap(K toKey)abstract SortedMap<K, V>         subMap(K fromKey, K toKey)abstract NavigableMap<K, V>      subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)abstract SortedMap<K, V>         tailMap(K fromKey)abstract NavigableMap<K, V>      tailMap(K fromKey, boolean inclusive)

说明:

NavigableMap除了继承SortedMap的特性外,它的提供的功能可以分为4类:

第1类,提供操作键-值对的方法。lowerEntry、floorEntry、ceilingEntry 和 higherEntry 方法,它们分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象。
firstEntry、pollFirstEntry、lastEntry 和 pollLastEntry 方法,它们返回和/或移除最小和最大的映射关系(如果存在),否则返回 null。

第2类,提供操作键的方法。这个和第1类比较类似lowerKey、floorKey、ceilingKey 和 higherKey 方法,它们分别返回与小于、小于等于、大于等于、大于给定键的键。

第3类,获取键集。navigableKeySet、descendingKeySet分别获取正序/反序的键集。

第4类,获取键-值对的子集。

6 Dictionary

Dictionary的定义如下:

public abstract class Dictionary<K,V> {}

NavigableMap是JDK 1.0定义的键值对的接口,它也包括了操作键值对的基本函数。

abstract Enumeration<V>     elements()abstract V                  get(Object key)abstract boolean            isEmpty()abstract Enumeration<K>     keys()abstract V                  put(K key, V value)abstract V                  remove(Object key)abstract int                size()

存放键值对,Map中的值也可以是一个容器

在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值

实现map的有:HashMap、TreeMap、HashTable、WeakHashMap。

HashMap
以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。

TreeMap

键以某种排序规则排序,内部以red-black(红-黑)树数据结构实现,实现了SortedMap接口

HashTable
也是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式,不过性能比HashMap要低

Queue接口

public interface Queue<E> extends Collection<E>
//添加 boolean add(E e);//增加一个元素,如果队列已满,则抛出一个IIIegaISlabEepeplian异常 boolean offer(E e);添加一个元素并返回true,如果队列已满,则返回false //移除 E remove();  //移除并返回队列头元素,如果队列为空,则抛出一个NoSuchElementException异常 E poll(); //移除并返问队列头部的元素,如果队列为空,则返回null //取头元素 E element();//返回队列头部的元素 ,如果队列为空,则抛出一NoSuchElementException异常 E peek();//返回队列头部的元素,如果队列为空,则返回null

队列,它主要分为两大类,一类是阻塞式队列,队列满了以后再插入元素则会抛出异常,主要包括ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。

集合类的一些讨论

1、Vector和ArrayList

  1. vector是线程同步的,所以它也是线程安全的,而arraylist是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用arraylist效率比较高。
  2. 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
  3. 如果查找一个指定位置的数据,vector和arraylist使用的时间是相同的,都是0(1),这个时候使用vector和arraylist都可以。而如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度,这个时候就应该考虑到使用linklist,因为它移动一个指定位置的数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。

ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入数度较快!

2、Aarraylist和Linkedlist

  1. ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
  2. 对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针。
  3. 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

3、HashMap与TreeMap

  1. HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
  2. 集合框架”提供两种常规的Map实现:HashMap和TreeMap (TreeMap实现SortedMap接口)。
  3. 在Map 中插入、删除和定位元素,HashMap是最好的选择。但如果您要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。使用HashMap要求添加的键类明确定义了hashCode()和 equals()的实现。 这个TreeMap没有调优选项,因为该树总处于平衡状态。

4、hashtable与hashmap

1、历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现 。
2、同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的 。
3、值:只有HashMap可以让你将空值作为一个表的条目的key或value 。

对集合的选择

1、对List的选择

  1. 对于随机查询与迭代遍历操作,数组比所有的容器都要快。所以在随机访问中一般使用ArrayList
  2. LinkedList使用双向链表对元素的增加和删除提供了非常好的支持,而ArrayList执行增加和删除元素需要进行元素位移。
  3. 对于Vector而已,我们一般都是避免使用。
  4. 将ArrayList当做首选,毕竟对于集合元素而已我们都是进行遍历,只有当程序的性能因为List的频繁插入和删除而降低时,再考虑LinkedList。

2、对Set的选择

  1. HashSet由于使用HashCode实现,所以在某种程度上来说它的性能永远比TreeSet要好,尤其是进行增加和查找操作。
  2. 虽然TreeSet没有HashSet性能好,但是由于它可以维持元素的排序,所以它还是存在用武之地的。

3、对Map的选择

  1. HashMap与HashSet同样,支持快速查询。虽然HashTable速度的速度也不慢,但是在HashMap面前还是稍微慢了些,所以HashMap在查询方面可以取代HashTable。
  2. 由于TreeMap需要维持内部元素的顺序,所以它通常要比HashMap和HashTable慢。

[主要参考与转载]http://www.cnblogs.com/skywang12345/p/3323085.html

ps:

该大侠将java容器总结的很好,楼主本人只是学习了该大侠博客,对于某些地方及代码实例加了自己的想法。楼主写这博客只为了做个学习笔记自己看的,完全尊重原创,其他人最好看原博客的。

0 0
原创粉丝点击