第一个话题: 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