[转]HashMap深度分析与比较

来源:互联网 发布:3小时网络创业计划书 编辑:程序博客网 时间:2024/05/29 09:42

第一个话题: HashMap的内部实现
最先是看到这篇文章深有感触.
http://www.matrix.org.cn/article/984.html

我的结论:
1. HashMap内部基本是个散列表.初始容量DEFAULT_INITIAL_CAPACITY=16, loadfactor=0.75,实际初始容量为16X0.75=12
2. 使用put(key, value)时
        1). 根据HashMap的key算出hashcode,算法是native的, 看不到:(
        2). 得到hashcode之后, 算出这个key在散列表中的index
3. 对散列表index的entry进行询问, 条件是
        1) e.hash==key的hashcode(通过obj.hashcode()方法得到数值之后还有一系列操作才能得到ke的hashcode, 见HashMap.hash()方法)
        2) e.key==key || key.equals(e.key)

4. 如果询问有结果,就替代原obj,其实这里的put有返回的.
  HashMap hs = new HashMap();
  hs.put("key1", "string1");
  Object obj = hs.put("key1", "string2");
  System.out.println(obj);
  System.out.println(hs.get("key1"));
打印结果得到
string1
string2

5. hashtable的实现和hashmap的实现差不多,只是多了同步

第二个话题: 其他的Collection
1. TreeSet内部是使用compareTo, 而HashSet是equalsTo
   所以当加入new BigDecimal("1.0");
             new BigDecimal("1.00");时
   HashSet中将有两个元素,而TreeSet中只有一个

2. 一段小程序,演示LinkedHashSet:
import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;


public class Tree_MapAndSetTest {

    public static void main(String[] args) {
        String months[] =
          new DateFormatSymbols(Locale.US).getMonths();
        String italianMonths[] =
          new DateFormatSymbols(Locale.ITALIAN).getMonths();
        List list = Arrays.asList(months);
        Set orderedSet = new LinkedHashSet(list);
        Set unorderedSet = new HashSet(list);
        System.out.println("Ordered:   " + orderedSet);
        System.out.println("Unordered: " + unorderedSet);
       
       
        Map orderedMap = new LinkedHashMap();
        Map unorderedMap = new HashMap();
        for (int i=0, n=months.length; i < n; i++) {
          orderedMap.put(months[i], italianMonths[i]);
          unorderedMap.put(months[i], italianMonths[i]);
        }
        System.out.println("Ordered:   " + orderedMap);
        System.out.println("Unordered: " + unorderedMap);
       
       
        Collection values = orderedMap.values();
        for (Iterator i = values.iterator(); i.hasNext();
          System.out.println(i.next()));
         

        Map accessorderedMap =
          new LinkedHashMap(20, .80f, true);
        for (int i=0, n=months.length; i < n; i++) {
          accessorderedMap.put(months[i], italianMonths[i]);
        }
        accessorderedMap.get("June");
        accessorderedMap.get("April");
        accessorderedMap.get("February");
        System.out.println(accessorderedMap);

    }
}


结果是:
Ordered:   [January, February, March, April, May, June, July, August, September, October, November, December, ]
Unordered: [December, March, April, November, September, October, May, June, August, February, January, July, ]
Ordered:   {January=gennaio, February=febbraio, March=marzo, April=aprile, May=maggio, June=giugno, July=luglio, August=agosto, September=settembre, October=ottobre, November=novembre, December=dicembre, =}
Unordered: {March=marzo, December=dicembre, April=aprile, November=novembre, September=settembre, October=ottobre, May=maggio, June=giugno, August=agosto, January=gennaio, February=febbraio, July=luglio, =}
gennaio
febbraio
marzo
aprile
maggio
giugno
luglio
agosto
settembre
ottobre
novembre
dicembre

{January=gennaio, March=marzo, May=maggio, July=luglio, August=agosto, September=settembre, October=ottobre, November=novembre, December=dicembre, =, June=giugno, April=aprile, February=febbraio}


第三个话题: 最后再重复罗嗦下
HashMap和HashTable的区别
1 access to the Hashtable is synchronized on the table while access to the HashMap isn't
2 HashMap is fail-safe while the enumerator for the Hashtable isn't
3 HashMap permits null values in it, while Hashtable doesn't

 
原创粉丝点击