注意ConcurrentHashMap是并发包下的,其实现的也是并发包下的ConcurrentMap接口,该接口继承了Map接口。
Hashmap基于链表数组(红黑树),arraylist就是数组,linkedList基于双向链表。
注意set从没规范是否有顺序,只是规范了不能重复。例如LinkedHashSet即是有序的。
HashMap和LinkedHashMap的区别是LinkedHashMap在HashMap的基础上,采用双向链表(doubly-linkedlist)的形式将所有entry连接起来,这样是为保证元素的迭代顺序跟插入顺序相同。
除此之外,两者的遍历也不同,HashMap需要遍历整个table,包括数组链表和红黑树。而LinkedHashMap由于是双向链表,只需要从链表头部遍历链表即可。
1.Hashtable线程安全。而hashmap是非线程安全的,
2.hashmap允许null
3.hashmap的迭代器是fail-fast的,迭代过程中其他线程修改hashmap的结构,hashmap会抛ConcurrentModificationException。hashtble不是,在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。
1.ArrayList是实现了基于数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinedList可能比较占优势,但不一定,如果add的位置在list头部,arrayList要复制大量数组,效率较低。当add的位置在list尾部,反而是arrayList较快。
1) Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。
2)当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间。
WeakHashMap,从名字可以看出它是某种 Map。它的特殊之处在于 WeakHashMap 里的entry可能会被GC自动删除,即使程序员没有调用remove()或者clear()方法。由于这个特性,weakedHashMap特别适合做缓存。
更直观的说,当使用 WeakHashMap时,即使没有显示的添加或删除任何元素,也可能发生如下情况:
调用两次size()方法返回不同的值;
两次调用isEmpty()方法,第一次返回false,第二次返回true;
两次调用containsKey()方法,第一次返回true,第二次返回false,尽管两次使用的是同一个key;
两次调用get()方法,第一次返回一个value,第二次返回null,尽管两次使用的是同一个对象。
weakedHashMap里面的元素是弱引用的,如果外界没为这个元素加强引用,其依然会被Gc回收。
如果需要使 Map线程安全,大致有这么5种方法:
1、使用 synchronized关键字,代码如下
synchronized(anObject) {
value = map.get(key);
}
2、使用 JDK1.5提供的锁(java.util.concurrent.locks.Lock)。代码如下
lock.lock();
value = map.get(key);
lock.unlock();
3、使用 JDK1.5提供的读写锁(java.util.concurrent.locks.ReadWriteLock)。代码如下
rwlock.readLock().lock();
value = map.get(key);
rwlock.readLock().unlock();
这样两个读操作可以同时进行,理论上效率会比方法 2高。
4、使用 JDK1.5提供的 java.util.concurrent.ConcurrentHashMap类。该类将 Map的存储空间分为若干块,每块拥有自己的锁,大大减少了多个线程争夺同一个锁的情况。代码如下
value = map.get(key); //同步机制内置在 get方法中
5、使用Collections.synchronizedMap(new HashMap
比较:
1、不同步确实最快,与预期一致。
2、最上面的四种同步方式中,ConcurrentHashMap是最快的,接近不同步的情况。
3、synchronized关键字非常慢,比使用锁慢了两个数量级。如果需自己实现同步,则使用 JDK1.5提供的锁机制,避免使用 synchronized关键字。
一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个的所有属性和方法都会自动序列化。但是有种情况是有些属性是不需要序列号的,所以就用到这个关键字。只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。