HashMap,LinkedHashMap,TreeMap都属于Map。
Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复。
HashMap 是一个最常用的Map,它根据键的 HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。
LinkedHashMap LinkedHashMap也是一个HashMap,但是内部维持了一个双向链表,可以保持顺序
TreeMap 不仅可以保持顺序,而且可以用于排序。
LinkedHashMap 是比 HashMap 多了一个链表的结构。与 HashMap 相比 LinkedHashMap 维护的是一个具有
双重链表的HashMap,LinkedHashMap 支持两种排序,一种是插入排序,一种是使用排序,最近使用的会移至尾部例如 M1 M2 M3 M4,使用M3后为 M1 M2 M4 M3了,
LinkedHashMap 输出时其元素是有顺序的,而 HashMap 输出时是随机的,如果 Map 映射比较复杂而又要求高效率的话,最好使用 LinkedHashMap,但是多线程访问的话可能会造成不同步,所以要用 Collections.synchronizedMap 来包装一下,从而实现同步。其实现一般为:
- Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<String, String>());
Map<String, String> map = Collections.synchronizedMap(new LinkedHashMap<String, String>());
下面是一个 HashMap,LinkedHashMap,TreeMap 的综合使用例子,和简单的性能对比。
- package com.chen.java;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import java.util.Random;
- import java.util.TreeMap;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public class TestMap {
- public static void main(String[] args) {
- Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap<Integer, Integer>());
- Random ran = new Random();
- long l1 = System.currentTimeMillis();
- long l2 = 0;
- for (;;) {
- map.put(ran.nextInt(1000000), ran.nextInt(1000000));
- l2 = System.currentTimeMillis();
- if ((l2 - l1) > 2000) {
- break;
- }
- }
- long t1 = System.currentTimeMillis();
- testHashMap(map);
- long t2 = System.currentTimeMillis();
- System.out.println("HashMap cost :" + (t2 - t1) + " ms");
- testLinkedHashMap(map);
- t1 = System.currentTimeMillis();
- System.out.println("LinkedHashMap cost :" + (t1 - t2) + " ms");
- testTreeMap(map);
- t2 = System.currentTimeMillis();
- System.out.println("TreeMap cost :" + (t2 - t1) + " ms");
- }
- public static void testHashMap(Map map) {
- Map<Integer, Integer> mymap = new HashMap<Integer, Integer>();
- mymap.putAll(map);
- for (Iterator it = mymap.values().iterator(); it.hasNext();) {
- it.next();
-
- }
- }
- public static void testLinkedHashMap(Map map) {
- Map<Integer, Integer> mymap = new LinkedHashMap<Integer, Integer>();
- mymap.putAll(map);
- for (Iterator it = mymap.values().iterator(); it.hasNext();) {
- it.next();
-
- }
- }
- public static void testTreeMap(Map map) {
- Map<Integer, Integer> mymap = new TreeMap<Integer, Integer>(
-
-
-
-
-
-
-
- );
- mymap.putAll(map);
- for (Iterator it = mymap.keySet().iterator(); it.hasNext();) {
- it.next();
-
- }
- }
- }
package com.chen.java;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TestMap {
public static void main(String[] args) {
Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap<Integer, Integer>());
Random ran = new Random();
long l1 = System.currentTimeMillis();
long l2 = 0;
for (;;) {
map.put(ran.nextInt(1000000), ran.nextInt(1000000));
l2 = System.currentTimeMillis();
if ((l2 - l1) > 2000) {
break;
}
}
long t1 = System.currentTimeMillis();
testHashMap(map);
long t2 = System.currentTimeMillis();
System.out.println("HashMap cost :" + (t2 - t1) + " ms");
testLinkedHashMap(map);
t1 = System.currentTimeMillis();
System.out.println("LinkedHashMap cost :" + (t1 - t2) + " ms");
testTreeMap(map);
t2 = System.currentTimeMillis();
System.out.println("TreeMap cost :" + (t2 - t1) + " ms");
}
public static void testHashMap(Map map) {
Map<Integer, Integer> mymap = new HashMap<Integer, Integer>();
mymap.putAll(map);
for (Iterator it = mymap.values().iterator(); it.hasNext();) {
it.next();
// System.out.println(it.next());
}
}
public static void testLinkedHashMap(Map map) {
Map<Integer, Integer> mymap = new LinkedHashMap<Integer, Integer>();
mymap.putAll(map);
for (Iterator it = mymap.values().iterator(); it.hasNext();) {
it.next();
// System.out.println(it.next());
}
}
public static void testTreeMap(Map map) {
Map<Integer, Integer> mymap = new TreeMap<Integer, Integer>(/*new Comparator<Object>() {
Collator c = Collator.getInstance();
@Override
public int compare(Object o1, Object o2) {
CollationKey key1 = c.getCollationKey(o1.toString());
CollationKey key2 = c.getCollationKey(o2.toString());
return key1.compareTo(key2);
}
}*/);
mymap.putAll(map);
for (Iterator it = mymap.keySet().iterator(); it.hasNext();) {
it.next();
//System.out.println(it.next());
}
}
}
其中一次运行结果如下:
- HashMap cost :781 ms
- LinkedHashMap cost :219 ms
- TreeMap cost :547 ms
HashMap cost :781 ms
LinkedHashMap cost :219 ms
TreeMap cost :547 ms
package com.demo.map;
import java.io.Serializable;
import java.text.CollationKey;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* @author cgy
* 本类是用来操作HashMap、linkedHashMap、TreeMap的
* 理解他们之间的差异。
* */
@SuppressWarnings({"serial","unchecked"})
public class OperateMap implements Serializable {
public static String name ;
public static Map<String, String> map ;
public static void main(String[] arg0){
operateHashMap();
operateHashMapSynchronized();
operateLinkedHashMap();
operateHashMapSynchronized();
operateTreeMap();
operateTreeMapOrder();
}
/*********************HashMap(不同步,输出元素是随机的,没有顺序)**************************************/
/**
* 操作HashMap 线程不同步是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有
* 很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;
* 但是它输出数据是随机的,没有顺序。
* */
public static void operateHashMap(){
map = new HashMap<String, String>();
map.put("name10", "吴飞1") ;
map.put("name11", "曹雄2");
map.put("name12", "王晓明3");
printOutValue(map) ;
}
/**
* 操作HashMap线程同步
* HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;
* 可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法
* 使HashMap具有同步的能力。
* */
public static void operateHashMapSynchronized(){
map = Collections.synchronizedMap(new HashMap<String, String>()) ;
map.put("name13", "吴飞1") ;
map.put("name14", "曹雄2");
map.put("name15", "王晓明3");
printOutValue(map);
}
/*********************LinkedHashMap(不同步,输出元素有顺序)**************************************/
/**
* 操作HashMap 线程不同步
* LinkedHashMap是比HashMap多了一个链表的结构。与HashMap相比LinkedHashMap维护的是一个具有双重链表的HashMap,
* LinkedHashMap支持2中排序一种是插入排序,一种是使用排序,最近使用的会移至尾部例如 M1 M2 M3 M4,
* 使用M3后为 M1 M2 M4 M3了,LinkedHashMap输出时其元素是有顺序的,
* */
public static void operateLinkedHashMap(){
map = new LinkedHashMap<String, String>();
map.put("name20", "吴飞1") ;
map.put("name21", "曹雄2");
map.put("name22", "王晓明3");
printOutValue(map) ; //输出数据是有顺序的
}
/**
* 操作HashMap线程同步
* 如果Map映射比较复杂而又要求高效率的话,最好使用LinkedHashMap,
* 但是多线程访问的话可能会造成不同步,所以要用Collections.synchronizedMap
* 来包装一下,从而实现同步
* */
public static void operateLinkedHashMapSynchronized(){
map = Collections.synchronizedMap(new LinkedHashMap<String, String>()) ;
map.put("name23", "吴飞1") ;
map.put("name24", "曹雄2");
map.put("name25", "王晓明3");
printOutValue(map);
}
/*********************TreeMap(不仅可以保持顺序,而且可以用于排序)**************************************/
public static void operateTreeMap(){
map = Collections.synchronizedMap(new TreeMap<String, String>()) ;
map.put("name33", "吴飞1") ;
map.put("name34", "曹雄2");
map.put("name35", "王晓明3");
printOutValue(map);
}
public static void operateTreeMapOrder(){
map = new TreeMap<String, String>(new Comparator<Object>(){
/**
* Collator 类执行区分语言环境的 String 比较。使用此类可为自然语言文本构建搜索和排序例程。
* Collator 是一个抽象基类,如果正好比较 String 一次,则 compare 方法可提供最佳性能。
* 但在对 String 列表排序时,通常需要对每个 String 进行多次比较。
* 在这种情况下,CollationKey 可提供更好的性能。CollationKey 类将一个 String 转换成一系列可与其他 CollationKey 进行按位比较的位。
* CollationKey 是由 Collator 对象为给定的 String 所创建的。
* 不能直接创建 CollationKey。而是通过调用 Collator.getCollationKey 来生成。
* 只能比较同一个 Collator 对象生成的 CollationKey。 下面创建Collator对象
* */
Collator collator = Collator.getInstance() ;
public int compare(Object o1, Object o2) {
//collator.compare(o1, o2); //如果正好比较 String 一次,则 compare 方法可提供最佳性能
/**
* CollationKey 表示遵守特定 Collator 对象规则的 String。
* 比较两个 CollationKey 将返回它们所表示的 String 的相对顺序。
* 使用 CollationKey 来比较 String 通常比使用 Collator.compare 更快。
* 因此,当必须多次比较 String 时(例如,对一个 String 列表进行排序),
* 使用 CollationKey 会更高效。
* */
CollationKey key1 = collator.getCollationKey(o1.toString());
CollationKey key2 = collator.getCollationKey(o2.toString());
return key1.compareTo(key2);
}});
map.put("name30", "曹雄1") ;
map.put("name31", "曹雄2");
map.put("name32", "王晓明3");
printOutValue(map);
}
/**
* 打印值
* */
private static void printOutValue(Map<String, String> map) {
for (Iterator<String> iterator=map.values().iterator();iterator.hasNext();) {
name = iterator.next() ;
System.out.println(name);
}
System.out.println(""); //换行
}
}