﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-himalayas-随笔分类-JAVA</title><link>http://www.blogjava.net/himalayas/category/50230.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 12 Jun 2014 14:35:17 GMT</lastBuildDate><pubDate>Thu, 12 Jun 2014 14:35:17 GMT</pubDate><ttl>60</ttl><item><title>install jar to repository</title><link>http://www.blogjava.net/himalayas/archive/2014/06/12/414667.html</link><dc:creator>himalayas</dc:creator><author>himalayas</author><pubDate>Thu, 12 Jun 2014 09:23:00 GMT</pubDate><guid>http://www.blogjava.net/himalayas/archive/2014/06/12/414667.html</guid><wfw:comment>http://www.blogjava.net/himalayas/comments/414667.html</wfw:comment><comments>http://www.blogjava.net/himalayas/archive/2014/06/12/414667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/himalayas/comments/commentRss/414667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/himalayas/services/trackbacks/414667.html</trackback:ping><description><![CDATA[<div>mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=6.0.0 -Dpackaging=jar -Dfile=C:\ojdbc6.jar</div><img src ="http://www.blogjava.net/himalayas/aggbug/414667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/himalayas/" target="_blank">himalayas</a> 2014-06-12 17:23 <a href="http://www.blogjava.net/himalayas/archive/2014/06/12/414667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HashMap解析</title><link>http://www.blogjava.net/himalayas/archive/2011/01/10/342656.html</link><dc:creator>himalayas</dc:creator><author>himalayas</author><pubDate>Mon, 10 Jan 2011 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/himalayas/archive/2011/01/10/342656.html</guid><wfw:comment>http://www.blogjava.net/himalayas/comments/342656.html</wfw:comment><comments>http://www.blogjava.net/himalayas/archive/2011/01/10/342656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/himalayas/comments/commentRss/342656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/himalayas/services/trackbacks/342656.html</trackback:ping><description><![CDATA[<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">HashMap是基于哈希表的Map接口的实现，允许null值和null键（HashMap和Hashtable大致一样，除了不同步和允许null外）。HashMap不保存映射的顺序，特别是不保证该顺序恒久不变。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HashMap的实现假定hash函数将各个元素正确分布在各桶之间，可为基本操作（如get()和set()）提供稳定的性能，迭代集合视图所需的时间与<tt>HashMap</tt>&nbsp;实例的&#8220;容量&#8221;（桶的数量）及其大小（键-值映射关系数）的和成比例。所以，如果迭代性能很重要，则不要将初始容量设置得太高（或将加载因子设置得太低）。 （注：这段同HashSet很相似，其实HashSet是基本HashMap实现的，所以在性能的控制上也一样）</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 21px; font-family: 'Courier New'; ">HashMap</span>&nbsp;的实例有两个参数影响其性能：初始容量和加载因子。容量是哈希表中桶的数量，初始容量只是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时，通过调用&nbsp;<tt>rehash</tt>&nbsp;方法将容量翻倍。HashMap的默认初始容量是16，默认加载因子是0.75，这样，当HashMap里的元素超过16*0.75即12时，调用rehash方法，使容量增长一倍。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通常，默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销，但同时也增加了查询成本（在大多数&nbsp;<tt>HashMap</tt>类的操作中，包括&nbsp;<tt>get</tt>&nbsp;和&nbsp;<tt>put</tt>&nbsp;操作，都反映了这一点）。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子，以便最大限度地降低&nbsp;<tt>rehash</tt>&nbsp;操作次数。如果初始容量大于最大条目数除以加载因子，则不会发生&nbsp;<tt>rehash</tt>&nbsp;操作。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果很多映射关系要存储在&nbsp;<tt>HashMap</tt>&nbsp;实例中，则相对于按需执行自动的 rehash 操作以增大表的容量来说，使用足够大的初始容量创建它将使得映射关系能更有效地存储。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意，此实现不是同步的。</strong>&nbsp;如果多个线程同时访问此映射，而其中至少一个线程从结构上修改了该映射，则它<em style="font-style: italic; ">必须</em>&nbsp;保持外部同步。（结构上的修改是指添加或删除一个或多个映射关系的操作；仅改变与实例已经包含的键关联的值不是结构上的修改。）这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象，则应该使用&nbsp;<tt>Collections.synchronizedMap</tt>&nbsp;方法来&#8220;包装&#8221;该映射。最好在创建时完成这一操作，以防止对映射进行意外的不同步访问，如下所示：</p>
<span style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">
<pre>     Map m = Collections.synchronizedMap(new HashMap(...));      </pre>
</span><span style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">
<pre><p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">       由所有此类的&#8220;集合视图方法&#8221;所返回的迭代器都是快速失败的：在迭代器创建之后，如果从结构上对映射进行修改，除非通过迭代器</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">自身的 <tt>remove</tt>
或 <tt>add</tt>
方法，其他任何时间任何方式的修改，迭代器都将抛出 <tt>ConcurrentModificationException</tt>
。因此，面对并发</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">的修改，迭代器很快就会完全失败，而不冒在将来不确定的时间任意发生不确定行为的风险。 </p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">      注意，迭代器的快速失败行为不能得到保证，一般来说，存在不同步的并发修改时，不可能作出任何坚决的保证。快速失败迭代器尽最大</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">努力抛出 <tt>ConcurrentModificationException</tt>
。因此，编写依赖于此异常程序的方式是错误的，正确做法是：迭代器的快速失败行为应</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">该仅用于检测程序错误<em style="font-style: italic; ">。</em>
HashMap的构造函数：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">         public HashMap(int initialCapacity, float loadFactor) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (initialCapacity &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalArgumentException("Illegal initial capacity: " +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initialCapacity);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (initialCapacity &gt; MAXIMUM_CAPACITY)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initialCapacity = MAXIMUM_CAPACITY;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (loadFactor &lt;= 0 || Float.isNaN(loadFactor))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalArgumentException("Illegal load factor: " +<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loadFactor);</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Find a power of 2 &gt;= initialCapacity<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int capacity = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (capacity &lt; initialCapacity) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; capacity &lt;&lt;= 1;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.loadFactor = loadFactor;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threshold = (int)(capacity * loadFactor);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table = new Entry[capacity];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init();<br />
&nbsp;&nbsp;&nbsp; }</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">         可以看出，当生成HashMap对象时，如果initialCapacity的数值比较大时，capacity 会被赋于等于或大于initialCapacity 的值，然后</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">创建一个有capacity 个Entry对象的table数组，所以initialCapacity的数值不能太大，否则会生成比较大的数组table，占用比较大的应用内</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">存，造成内存浪费。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">         HashMap的默认构造函数：</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">         public HashMap() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.loadFactor = DEFAULT_LOAD_FACTOR;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table = new Entry[DEFAULT_INITIAL_CAPACITY];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init();<br />
&nbsp;&nbsp;&nbsp; }</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">          默认构造函数里的初始容量为16，加载因子为0.75，这样会生成含有16*0.75=12个Entry对象的数组table，当HashMap里的元素数</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">量超过12个时，会将HashMap的容量翻1倍，生成包含32个Entry对象的数组。</p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; ">          <span style="line-height: 19px; font-size: medium; ">put方法：</span>
<br />
</p>
</pre>
</span>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="line-height: 24px; font-size: medium; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public V put(K key, V value) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; K k = maskNull(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int hash = hash(k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = indexFor(hash, table.length);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Entry&lt;K,V&gt; e = table[i]; e != null; e = e.next) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (e.hash == hash &amp;&amp; eq(k, e.key)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; V oldValue = e.value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.value = value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.recordAccess(this);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return oldValue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; modCount++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addEntry(hash, k, value, i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br />
&nbsp;&nbsp;&nbsp; }</span></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="line-height: 24px; font-size: medium; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; K k = maskNull(key);这行是判断key是否为null，如果为null，则返回一个静态的K（Object）对象做为键值，这就是HashMap为什么允许null键存在的原因。</span></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="line-height: 24px; font-size: medium; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int hash = hash(k);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = indexFor(hash, table.length);</span></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; "><span style="line-height: 24px; font-size: medium; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这连续的两步就是 HashMap 最牛的地方！研究完我都汗颜了，其中 hash 就是通过 key 这个Object的 hashcode 进行 hash，然后通过 indexFor 获得在Object table的索引值。</span></p>
<p style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 1em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 24px; font-size: medium; ">&nbsp;table？？？不要惊讶，其实HashMap也神不到哪里去，它就是用 table 来放的。最牛的就是用 hash 能正确的返回索引。其中的hash算法，我跟JDK的作者 Doug 联系过，他建议我看看《The art of programing vol3》可恨的是，我之前就一直在找，我都找不到，他这样一提，我就更加急了，可惜口袋空空啊！！！<br />
不知道大家有没有留意 put 其实是一个有返回的方法，它会把相同键值的 put 覆盖掉并返回旧的值！如下方法彻底说明了 HashMap 的结构，其实就是一个表加上在相应位置的Entry的链表：<br />
for (Entry e = table; e != null; e = e.next) {<br />
if (e.hash == hash &amp;&amp; eq(k, e.key)) {<br />
Object oldvalue = e.value;<br />
e.value = value; //把新的值赋予给对应键值。<br />
e.recordAccess(this); //空方法，留待实现<br />
return oldvalue; //返回相同键值的对应的旧的值。<br />
}<br />
}<br />
modCount++; //结构性更改的次数<br />
addEntry(hash, k, value, i); //添加新元素，关键所在！<br />
return null; //没有相同的键值返回<br />
}&nbsp;<br />
我们把关键的方法拿出来分析：<br />
void addEntry(int hash, Object key, Object value, int bucketIndex) {<br />
table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);&nbsp;<br />
因为 hash 的算法有可能令不同的键值有相同的hash码并有相同的table索引，如：key＝&#8220;33&#8221;和key＝Object g的hash都是－8901334，那它经过indexfor之后的索引一定都为i，这样在new的时候这个Entry的next就会指向这个原本的 table，再有下一个也如此，形成一个链表，和put的循环对定e.next获得旧的值。到这里，HashMap的结构，大家也十分明白了吧？<br />
if (size++ &gt;= threshold) //这个threshold就是能实际容纳的量<br />
resize(2 * table.length); //超出这个容量就会将Object table重构&nbsp;<br />
所谓的重构也不神，就是建一个两倍大的table（我在别的论坛上看到有人说是两倍加1，把我骗了），然后再一个个indexfor进去！注意！！这就是效率！！如果你能让你的HashMap不需要重构那么多次，效率会大大提高！<br />
说到这里也差不多了，get比put简单得多，大家，了解put，get也差不了多少了。对于collections我是认为，它是适合广泛的，当不完 全适合特有的，如果大家的程序需要特殊的用途，自己写吧，其实很简单。（作者是这样跟我说的，他还建议我用LinkedHashMap,我看了源码以后发 现，LinkHashMap其实就是继承HashMap的，然后override相应的方法，有兴趣的同人，自己looklook）建个 Object table，写相应的算法，就ok啦。<br />
举个例子吧，像 Vector，list 啊什么的其实都很简单，最多就多了的同步的声明，其实如果要实现像Vector那种，插入，删除不多的，可以用一个Object table来实现，按索引存取，添加等。<br />
如果插入，删除比较多的，可以建两个Object table，然后每个元素用含有next结构的一个table存，如果要插入到i，但是i已经有元素，用next连起来，然后size＋＋，并在另一个table记录其位置。</span></p><img src ="http://www.blogjava.net/himalayas/aggbug/342656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/himalayas/" target="_blank">himalayas</a> 2011-01-10 09:39 <a href="http://www.blogjava.net/himalayas/archive/2011/01/10/342656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>