工做忙起來後,許久不看算法,居然DFA敏感詞算法都要看好一陣才能理解。。。真是和三階魔方還原手法同樣,田園將蕪,很是惋惜啊。算法
在DFA算法中,第一步是須要理解它的數據結構,在此基礎上,涉及到一些Hashmap的賦值。這裏的賦值很是有趣,三個Hashmap翻來覆去賦值,就解決了敏感詞表的初始化。數據結構
裏面都是屬於下文中的Hashmap「淺拷貝」,那麼究竟Java中的Hashmap有哪些拷貝方法呢?app
HashMap hm_source = new HashMap(); HashMap hm_clone = new HashMap(); hm_source.put("1", "1"); // hashmap deep clone method 1 hm_clone = (HashMap)hm_source.clone(); // hashmap deep clone method 2 hm_clone.putAll(hm_source);// hashmap shadow clone // hm_b = hm_a; hm_source.put("2", "2"); System.out.println("hm_source增長元素後,hm_source:"+hm_source); System.out.println("hm_source增長元素後,hm_clone:"+hm_clone); System.out.println("是否指向同一內存地址:"+(hm_source==hm_clone)); System.out.println("第一個元素是否指向同一內存地址:"+(hm_source.get(1)==hm_clone.get(1)));
上面介紹了兩種Hashmap深拷貝的方法,分別是hashmap.clone()和hashmap.putAll(hm_source),效果同樣,輸出以下:ide
hm_source增長元素後,hm_source:{1=1, 2=2} hm_source增長元素後,hm_clone:{1=1} 是否指向同一內存地址:false 第一個元素是否指向同一內存地址:true
那麼淺拷貝呢?(代碼中註釋的那段,直接等號=賦值),輸出以下:函數
hm_source增長元素後,hm_source:{1=1, 2=2} hm_source增長元素後,hm_clone:{1=1, 2=2} 是否指向同一內存地址:true 第一個元素是否指向同一內存地址:true
不難發現,深淺拷貝確實如其名,學習
深拷貝:兩個Hashmap對象彷佛完全無關,互相增長修改元素後,都不影響對方;測試
淺拷貝:兩個Hashmap對象就是「軟連接ln」,互相牽制,你改動了,我也跟着變。this
我黨的思想路線是實事求是,預想剖析根本區別,你們能夠看看JDK clone函數的源碼。spa
可是從現象咱們獲得的初步結論有幾點:.net
關於結論3.2,我也是在 HashMap的clone方法 博文中學習到了,裏面使用的Hashmap元素是Bean類型的,深拷貝下的元素修改,也會「打斷骨頭連着筋」地讓兩個Hashmap同時更新。
可是僅限於「元素修改」,如若「元素增刪」,那兩個Hashmap對象就「翻臉不認人」了,不會同步更新。
JDK是個可貴的學習材料,源碼仍是要讀的。如今也粘貼過來,作一些記錄。
/** * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and * values themselves are not cloned. * 【我們中文叫「深拷貝」,老外美其名曰「拷貝一份實例的'淺拷貝'」,更加嚴謹】 * @return a shallow copy of this map */ @SuppressWarnings("unchecked") @Override public Object clone() { HashMap<K,V> result; try { result = (HashMap<K,V>)super.clone(); } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } result.reinitialize(); result.putMapEntries(this, false); return result; }
/** * Implements Map.putAll and Map constructor * * @param m the map * @param evict false when initially constructing this map, else * true (relayed to method afterNodeInsertion). */ final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) { int s = m.size(); if (s > 0) { if (table == null) { // pre-size float ft = ((float)s / loadFactor) + 1.0F; int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft : MAXIMUM_CAPACITY); if (t > threshold) threshold = tableSizeFor(t); } else if (s > threshold) resize(); for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) { K key = e.getKey(); V value = e.getValue(); //【putVal方法裏面我初步掃了一下,也未涉及Hashmap instance對象的新建,是一些Hashmap結構中的Node的新建】 putVal(hash(key), key, value, false, evict); } } }
以代碼最終解釋權由JDK1.8.x全部。