HashMap 是将 Key 做 Hash 算法,然后将 Hash 值映射到内存地址,直接取得 Key 所对应的数据。

 

在 HashMap 中,底层数据结构使用的是数组,所谓的内存地址即数组的下标索引。

HashMap 的高性能需要保证以下几点:

1. Hash 算法必须是高效的;

2. Hash 值到内存地址 (数组索引) 的算法是快速的;

3. 根据内存地址 (数组索引) 可以直接取得对应的值。

HashMap 实际上是一个链表的数组。基于 HashMap 的链表方式实现机制,只要 HashCode() 和 Hash() 方法实现得足够好,能够尽可能地减少冲突的产生,那么对 HashMap 的操作几乎等价于对数组的随机访问操作,具有很好的性能。但是,如果 HashCode() 或者 Hash() 方法实现较差,在大量冲突产生的情况下,HashMap 事实上就退化为几个链表,对 HashMap 的操作等价于遍历链表,此时性能很差。

HashMap 的一个功能缺点是它的无序性,被存入到 HashMap 中的元素,在遍历 HashMap 时,其输出是无序的。如果希望元素保持输入的顺序,可以使用 LinkedHashMap 替代。

LinkedHashMap 继承自 HashMap,具有高效性,同时在 HashMap 的基础上,又在内部增加了一个链表,用以存放元素的顺序。

HashMap 通过 hash 算法可以最快速地进行 Put() 和 Get() 操作。TreeMap 则提供了一种完全不同的 Map 实现。从功能上讲,TreeMap 有着比 HashMap 更为强大的功能,它实现了 SortedMap 接口,这意味着它可以对元素进行排序。TreeMap 的性能略微低于 HashMap。如果在开发中需要对元素进行排序,那么使用 HashMap 便无法实现这种功能,使用 TreeMap 的迭代输出将会以元素顺序进行。LinkedHashMap 是基于元素进入集合的顺序或者被访问的先后顺序排序,TreeMap 则是基于元素的固有顺序 (由 Comparator 或者 Comparable 确定)。

LinkedHashMap 是根据元素增加或者访问的先后顺序进行排序,而 TreeMap 则根据元素的 Key 进行排序。

 

测试示例

package mapKeySet;  
  
import java.util.HashMap;  
import java.util.LinkedHashMap;  
import java.util.Map;  
import java.util.TreeMap;  
  
/** 
 * @author mimvp.com
 * 2016.12.28
 */  
public class KeySetTest {  
    public static void main(String[] args) {  
        Map<String, String> map = new HashMap<String, String>();  
        map.put("a", "1");  
        map.put("b", "2");  
        map.put("c", "3");  
        map.put("d", "4");  
          
        System.out.print("HashMap:");  
        for(String key : map.keySet()) {  
            System.out.print(map.get(key) + " ");  
        }  
          
        Map<String, String> linkedMap = new LinkedHashMap<String, String>();  
        linkedMap.put("a", "1");  
        linkedMap.put("b", "2");  
        linkedMap.put("c", "3");  
        linkedMap.put("d", "4");  
          
        System.out.print("LinkedHashMap:");  
        for(String key : linkedMap.keySet()) {  
            System.out.print(linkedMap.get(key) + " ");  
        }  
          
        Map<String, String> treeMap = new TreeMap<String, String>();  
        treeMap.put("a", "1");  
        treeMap.put("b", "2");  
        treeMap.put("c", "3");  
        treeMap.put("d", "4");  
          
        System.out.print("TreeMap:");  
        for(String key : treeMap.keySet()) {  
            System.out.print(treeMap.get(key) + " ");  
        }  
    }  
}  

运行结果:

HashMap:4 2 3 1 LinkedHashMap:1 2 3 4 TreeMap:1 2 3 4  

 

Map 排序

	// HashMap
	public static void TestHashMap() {
		// 无序
		Map<String, String> map = new HashMap<String, String>();
		map.put("aaa", "111");
		map.put("bbb", "222");
		map.put("ccc", "333");
		System.out.println("TestHashMap - map : " + map.toString());

		// 有序
		Map<String, String> map2 = new TreeMap<String, String>();
		map2.put("aaa", "111");
		map2.put("bbb", "222");
		map2.put("ccc", "333");
		System.out.println("TestHashMap - map2 : " + map2.toString());

		// 有序
		Map<String, String> map3 = new LinkedHashMap<String, String>();
		map3.put("aaa", "111");
		map3.put("bbb", "222");
		map3.put("ccc", "333");
		System.out.println("TestHashMap - map3 : " + map3.toString());
	}

运行结果:

TestHashMap - map : {aaa=111, ccc=333, bbb=222}
TestHashMap - map2 : {aaa=111, bbb=222, ccc=333}
TestHashMap - map3 : {aaa=111, bbb=222, ccc=333}

 

Map 遍历

	public static void MapDemo() {
		HashMap<String, Integer> map = new HashMap<String, Integer>();
		map.put("语文", 1);
		map.put("数学", 2);
		map.put("英语", 3);
		map.put("历史", 4);
		map.put("政治", 5);
		map.put("地理", 6);
		map.put("生物", 7);
		map.put("化学", 8);
		for(Entry<String, Integer> entry : map.entrySet()) {
			System.out.println(entry.getKey() + " : " + entry.getValue());
		}
	}

运行结果:

政治 : 5
生物 : 7
历史 : 4
数学 : 2
化学 : 8
语文 : 1
英语 : 3
地理 : 6

 

 

参考推荐

Java HashMap工作原理及实现