Lopoincare's Blog

那逝去的一切,将消失在时间之中,却会留在记忆的某个角落…… 记下属于我们的那一小片记忆……

« 分享:梁静茹的56首经典歌曲,可以感动你一辈子的想让自己老婆成为全世界最幸福的女人吗?男人请进 »

Hashmap和Hashtable的相同点List,ArrayList和Vector的区别

HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable.可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别.
1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样.

2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以).

3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样.

4.HashTable使用Enumeration,HashMap使用Iterator.

5.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;

以上只是表面的不同,它们的实现也有很大的不同.

6.HashTable中hash数组默认大小是11,增加的方式是 old*2+1.HashMap中hash数组的默认大小是16,而且一定是2的指数.

7.哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新计算hash值,而且用与代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);

static int hash(Object x) {
  int h = x.hashCode();
  h += ~(h << 9);
  h ^= (h >>> 14);
  h += (h << 4);
  h ^= (h >>> 10);
  return h;
}
static int indexFor(int h, int length) {
  return h & (length-1);
}
以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如
HashMap对null的操作

Vector、ArrayList和List的异同
线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些类均在java.util包中.本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类.

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

Collection接口
  Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同的元素而另一些不行.一些能排序而另一些不行.Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的"子接口"如List和Set.
  所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素.后一个构造函数允许用户复制一个Collection.
  如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素.典型的用法如下:
    Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元素
    }
  由Collection接口派生的两个接口是List和Set.

List接口
  List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置.用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组.
和下面要提到的Set不同,List允许有相同的元素.
  除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历.
  实现List接口的常用类有LinkedList,ArrayList,Vector和Stack.

LinkedList类
  LinkedList实现了List接口,允许null元素.此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部.这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque).
  注意LinkedList没有同步方法.如果多个线程同时访问一个List,则必须自己实现访问同步.一种解决方法是在创建List时构造一个同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));

ArrayList类
  ArrayList实现了可变大小的数组.它允许所有元素,包括null.ArrayList没有同步.
size,isEmpty,get,set方法运行时间为常数.但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间.其他的方法运行时间为线性.
  每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小.这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义.当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率.
  和LinkedList一样,ArrayList也是非同步的(unsynchronized).

Vector类
  Vector非常类似ArrayList,但是Vector是同步的.由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常.

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

Set接口
  Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素.
  很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素.
  请注意:必须小心操作可变对象(Mutable Object).如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题.

发表评论:

Powered By Z-Blog 1.8 Arwen Build 90619
Copyright © Lopoincare's 博客