在Java当中,基本的数据结构有以下几种
- 向量(Vector)
- 枚举(Enumeration)
- 位集合(BitSet)
- 哈希表(Hashtable)
- 栈(Stack)
- 字典(Dictionary)
- 属性(Properties)
这里主要介绍前四种
Vector实现了一个动态数组,这个数组与ArrayList类似,不同点主要有以下几种
- Vector 是同步访问的。
- Vector 包含了许多传统的方法,这些方法不属于集合框架
Vector常用于事先不知道数组大小的情况下,而又同时需要改变数组的大小来满足容量的需要
常用的构造方法有以下几种
Vector v=new Vector(); //创建一个默认的向量,大小默认为10
Vector v=new Vector(int size);//创建一个指定size大小的向量,
Vector v=new Vector(Collection c);//创建一个包含指定集合c的向量
常用的方法有
v.addElement(Object element);//在数组末尾插入一个元素
v.add(int index, Object element);//在索引位置插入一个元素
v.elementAt(0);//返回索引为0的元素
v.capacity();//返回数组当前的长度
Enumeration是枚举类,它封装了遍历枚举元素的方法
Enumeration venom = v.elements();//定义一个枚举变量,枚举值为向量v的元素
//venom.hasMoreElements() 返回枚举变量是否有更多的元素(true或者false)
//venom.nextElement() 得到枚举变量元素的方法
while(venom.hasMoreElements()) {
System.out.println(venom.nextElement());//循环遍历输出每一个元素
}
BitSet是一种位集合类,封装的方法符合集合之间的的逻辑关系
BitSet的元素可以重复添加,但是同一个元素在集合中只能出现一次,并且BitSet中的数值数据是自动由小到大排序的
BitSet set1=new BitSet();//实例化BitSet对象
BitSet set2=new BitSet();//实例化BitSet对象
//添加几个元素(将位设置为ture)
set1.set(1);
set1.set(2);
set1.set(3);
set2.set(1);
set2.set(4);
set1.and(set2);//类似于集合当中的交集操作
set1.or(set2);//类似于集合当中的并集操作
set1.xor(set2);//找出两者不同的元素
此外,BitSet的元素允许通过get方法查询
set1.set(1);//将1位设为true
System.out.println(set1.get(1));//返回true
set1.clear(1);//将1位设为false
System.out.println(set1.get(1));//返回false
如果要用位数组来表示字母
set1.set((int)'a');
//使用强制转化
Hashmap
Hashmap内部采用数组加链表的数据存储方式
对于数据的存储位置,哈希内部有自己的一套散列算法,实现将元素均匀地分布在一个区间内,
如果某个数据与之前的 数据存储位置重复了,则会采取扩展链表的方式存储
HashMap <String,Integer> map=new HashMap <String,Integer>();//实例化一个对象
map.put("0", 10);//添加一个元素
map.remove("0", 10);//移除一个元素
//循环遍历
for(String key : map.keySet()){
map.get(key);
}
//迭代器遍历
Iterator<String> ite =map.keySet().iterator();
while( ite.hasNext()){
String key = ite.next();
map.get(key);
}
Hashtable
Hashtable<String,Integer> table=new Hashtable<String,Integer>();
哈希的不断迭代显示了不断更新的编程思想以及对高强度编程的需要
在这里进行对HashMap,Hashtable,ConcurrentHashMap的比较分析
首先在结构上进行考虑
HashMap和Hashtable都实现了Map接口,采用数组加链表的存储方式,数组中的每一个元素都是一个链表,该链表包含四个基础值,其中就有向下扩展的next节点。ConcurrentHashMap它是HashTable的替代,比HashTable的扩展性更好,在Java7中,ConcurrentHashMap被分成了若干个小的HashMap,也就是16个Segment(段,节点),每个Segment都是采用数组+链表的存储方式;而在Java8中,ConcurrentHashMap完全舍弃了这种结构,而是采用buckets数组与分离链接法,HashMap和Hashtable都是自动扩容的,HashMap扩容后大小是原来的两倍,Hashtable扩容后大小是原来的两倍+1。
同步(synchronization)与线程安全
在同步上,HashMap是非同步(synchronization)的,而Hashtable是同步(synchronization)的,这说明Hashtable是线程安全的,这意味着Hashtable同一时间只能有一个线程来访问,每个线程在访问它之前,都要获得同步锁,其他线程要在同步锁被释放之后再去获得同步锁及访问权(这样设计可能是因为多个线程同时访问可能会出现一些未知的问题,使得链表成环,或者链表乱序等)。
时间问题
我们都知道多线程可以让进程平行地做几件事,如果我们让多个线程访问同一个HashMap,这是并不安全的(上面已经提到了),所以多线程的程序最好是使用Hashtable,但是在单线程中,由于Hashtable是线程安全的,这意味着它的速度将会比HashMap慢一些,因此,在单线程中,还是用HashMap更加能够提升程序的运行速度。