最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?HashSet添加?遍歷元素源碼分析

 更新時間:2022年07月08日 15:40:54   作者:趙妹兒  
這篇文章主要為大家詳細(xì)介紹了HashSet、HashMap底層添加、遍歷元素的機制,追蹤并分析源碼,文中的示例代碼講解詳細(xì),希望對大學(xué)有所幫助

HashSet 類圖

HashSet 簡單說明

1.HashSet 實現(xiàn)了 Set 接口

2.HashSet 底層實際上是由 HashMap 實現(xiàn)的

public HashSet() {
        map = new HashMap<>();
}

3.可以存放 null,但是只能有一個 null

4.HashSet 不保證元素是有序的(即不保證存放元素的順序和取出元素的順序一致),取決于 hash 后,再確定索引的結(jié)果

5.不能有重復(fù)的元素

HashSet 底層機制說明

HashSet 底層是 HashMapHashMap 底層是 數(shù)組 + 鏈表 + 紅黑樹

模擬數(shù)組+鏈表的結(jié)構(gòu)

/**
 * 模擬 HashSet 數(shù)組+鏈表的結(jié)構(gòu)
 */
public class HashSetStructureMain {
    public static void main(String[] args) {
        // 模擬一個 HashSet(HashMap) 的底層結(jié)構(gòu)
        // 1. 創(chuàng)建一個數(shù)組,數(shù)組的類型為 Node[]
        // 2. 有些地方直接把 Node[] 數(shù)組稱為 表
        Node[] table = new Node[16];
        System.out.println(table);
        // 3. 創(chuàng)建節(jié)點
        Node john = new Node("john", null);
        table[2] = jhon; // 把節(jié)點 john 放在數(shù)組索引為 2 的位置
        Node jack = new Node("jack", null);
        jhon.next = jack; // 將 jack 掛載到 jhon 的后面
        Node rose = new Node("rose", null);
        jack.next = rose; // 將 rose 掛載到 jack 的后面
        Node lucy = new Node("lucy", null);
        table[3] = lucy; // 將 lucy 放在數(shù)組索引為 3 的位置
        System.out.println(table);

    }
}

// 節(jié)點類 存儲數(shù)據(jù),可以指向下一個節(jié)點,從而形成鏈表
class Node{
    Object item; // 存放數(shù)據(jù)
    Node next; // 指向下一個節(jié)點
    public Node(Object item, Node next){
        this.item = item;
        this.next = next;
    }
}

HashSet 添加元素底層機制

HashSet 添加元素的底層實現(xiàn)

1.HashSet 底層是 HashMap

2.當(dāng)添加一個元素時,會先得到 待添加元素的 hash 值,然后將其轉(zhuǎn)換成一個 索引值

3.查詢存儲數(shù)據(jù)表(Node 數(shù)組) table,看當(dāng)前 待添加元素 所對應(yīng)的 索引值 的位置是否已經(jīng)存放了 其它元素

4.如果當(dāng)前 索引值 所對應(yīng)的的位置不存在 其它元素,就將當(dāng)前 待添加元素 放到這個 索引值 所對應(yīng)的的位置

5.如果當(dāng)前 索引值 所對應(yīng)的位置存在 其它元素,就調(diào)用 待添加元素.equals(已存在元素) 比較,結(jié)果為 true,則放棄添加;結(jié)果為 false,則將 待添加元素 放到 已存在元素 的后面(已存在元素.next = 待添加元素)

HashSet 擴容機制

1.HashSet 的底層是 HashMap,第一次添加元素時,table 數(shù)組擴容到 cap = 16threshold(臨界值) = cap * loadFactor(加載因子 0.75) = 12

2.如果 table 數(shù)組使用到了臨界值 12,就會擴容到 cap * 2 = 32,新的臨界值就是 32 * 0.75 = 24,以此類推

3.在 Java8 中,如果一條鏈表上的元素個數(shù) 到達(dá) TREEIFY_THRESHOLD(默認(rèn)是 8),并且 table 的大小 >= MIN_TREEIFY_CAPACITY(默認(rèn)是 64),就會進(jìn)行 樹化(紅黑樹)

4.判斷是否擴容是根據(jù) ++size > threshold,即是否擴容,是根據(jù) HashMap 所存的元素個數(shù)(size)是否超過臨界值,而不是根據(jù) table.length() 是否超過臨界值

HashSet 添加元素源碼

/**
 * HashSet 源碼分析
 */
public class HashSetSourceMain {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add("java");
        hashSet.add("php");
        hashSet.add("java");
        System.out.println("set = " + hashSet);

        // 源碼分析
        // 1. 執(zhí)行 HashSet()
        /**
         * public HashSet() { // HashSet 底層是 HashMap
         *         map = new HashMap<>();
         *     }
         */

        // 2. 執(zhí)行 add()
        /**
         * public boolean add(E e) { // e == "java"
         *         // HashSet 的 add() 方法其實是調(diào)用 HashMap 的 put()方法
         *         return map.put(e, PRESENT)==null; // (static) PRESENT = new Object(); 用于占位
         *     }
         */

        // 3. 執(zhí)行 put()
        // hash(key) 得到 key(待存元素) 對應(yīng)的hash值,并不等于 hashcode()
        // 算法是 h = key.hashCode()) ^ (h >>> 16
        /**
         * public V put(K key, V value) {
         *         return putVal(hash(key), key, value, false, true);
         *     }
         */

        // 4. 執(zhí)行 putVal()
        // 定義的輔助變量:Node<K,V>[] tab; Node<K,V> p; int n, i;
        // table 是 HashMap 的一個屬性,初始化為 null;transient Node<K,V>[] table;
        // resize() 方法,為 table 數(shù)組指定容量
        // p = tab[i = (n - 1) & hash] 計算 key的hash值所對應(yīng)的 table 中的索引位置,將索引位置對應(yīng)的 Node 賦給 p
        /**
         * final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
         *                    boolean evict) {
         *         Node<K,V>[] tab; Node<K,V> p; int n, i; // 輔助變量
         *         // table 就是 HashMap 的一個屬性,類型是 Node[]
         *         // if 語句表示如果當(dāng)前 table 是 null,或者 table.length == 0
         *         // 就是 table 第一次擴容,容量為 16
         *         if ((tab = table) == null || (n = tab.length) == 0)
         *             n = (tab = resize()).length;
         *         // 1. 根據(jù) key,得到 hash 去計算key應(yīng)該存放到 table 的哪個索引位置
         *         // 2. 并且把這個位置的索引值賦給 i;索引值對應(yīng)的元素,賦給 p
         *         // 3. 判斷 p 是否為 null
         *         // 3.1 如果 p 為 null,表示還沒有存放過元素,就創(chuàng)建一個Node(key="java",value=PRESENT),并把這個元素放到 i 的索引位置
         *         // tab[i] = newNode(hash, key, value, null);
         *         if ((p = tab[i = (n - 1) & hash]) == null)
         *             tab[i] = newNode(hash, key, value, null);
         *         else {
         *             Node<K,V> e; K k; // 輔助變量
         *             // 如果當(dāng)前索引位置對應(yīng)的鏈表的第一個元素和待添加的元素的 hash值一樣
         *             // 并且滿足下面兩個條件之一:
         *             // 1. 待添加的 key 與 p 所指向的 Node 節(jié)點的key 是同一個對象
         *             // 2. 待添加的 key.equals(p 指向的 Node 節(jié)點的 key) == true
         *             // 就認(rèn)為當(dāng)前待添加的元素是重復(fù)元素,添加失敗
         *             if (p.hash == hash &&
         *                 ((k = p.key) == key || (key != null && key.equals(k))))
         *                 e = p;
         *             // 判斷 當(dāng)前 p 是不是一顆紅黑樹
         *             // 如果是一顆紅黑樹,就調(diào)用 putTreeVal,來進(jìn)行添加
         *             else if (p instanceof TreeNode)
         *                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
         *             else {
         *                  // 如果 當(dāng)前索引位置已經(jīng)形成一個 鏈表,就使用 for 循環(huán)比較
         *                  // 將待添加元素依次和鏈表上的每個元素進(jìn)行比較
         *                  // 1. 比較過程中如果出現(xiàn)待添加元素和鏈表中的元素有相同的,比較結(jié)束,出現(xiàn)重復(fù)元素,添加失敗
         *                  // 2. 如果比較到鏈表最后一個元素,鏈表中都沒出現(xiàn)與待添加元素相同的,就把當(dāng)前待添加元素放到該鏈表最后的位置
         *                  // 注意:在把待添加元素添加到鏈表后,立即判斷 該鏈表是否已經(jīng)到達(dá) 8 個節(jié)點
         *                  // 如果到達(dá),就調(diào)用 treeifyBin() 對當(dāng)前這個鏈表進(jìn)行數(shù)化(轉(zhuǎn)成紅黑樹)
         *                  // 注意:在轉(zhuǎn)成紅黑樹前,還要進(jìn)行判斷
         *                  // if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
         *                  //        resize();
         *                  // 如果上面條件成立,先對 table 進(jìn)行擴容
         *                  // 如果上面條件不成立,才轉(zhuǎn)成紅黑樹
         *                 for (int binCount = 0; ; ++binCount) {
         *                     if ((e = p.next) == null) {
         *                         p.next = newNode(hash, key, value, null);
         *                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
         *                             treeifyBin(tab, hash);
         *                         break;
         *                     }
         *                     if (e.hash == hash &&
         *                         ((k = e.key) == key || (key != null && key.equals(k))))
         *                         break;
         *                     p = e;
         *                 }
         *             }
         *             // e 不為 null ,說明添加失敗
         *             if (e != null) { // existing mapping for key
         *                 V oldValue = e.value;
         *                 if (!onlyIfAbsent || oldValue == null)
         *                     e.value = value;
         *                 afterNodeAccess(e);
         *                 return oldValue;
         *             }
         *         }
         *         ++modCount;
         *         // 擴容:說明判斷 table 是否擴容不是看 table 的length
         *         // 而是看 整個 HashMap 的 size(即已存元素個數(shù))
         *         if (++size > threshold)
         *             resize();
         *         afterNodeInsertion(evict);
         *         return null;
         *     }
         */
    }
}

HashSet 遍歷元素底層機制

HashSet 遍歷元素底層機制

1.HashSet 的底層是 HashMap,HashSet 的迭代器也是借由 HashMap 來實現(xiàn)的

2.HashSet.iterator() 實際上是去調(diào)用 HashMap 的 KeySet().iterator()

public Iterator<E> iterator() {
    return map.keySet().iterator();
}

3.KeySet() 方法返回一個 KeySet 對象,而 KeySet 是 HashMap 的一個內(nèi)部類

public Set<K> keySet() {
    Set<K> ks = keySet;
    if (ks == null) {
        ks = new KeySet();
        keySet = ks;
    }
    return ks;
}

4.KeySet().iterator() 方法返回一個 KeyIterator 對象,KeyIterator 是 HashMap 的一個內(nèi)部類

public final Iterator<K> iterator()     { return new KeyIterator(); }

5.KeyIterator 繼承了 HashIterator(HashMap的內(nèi)部類) 類,并實現(xiàn)了 Iterator 接口,即 KeyIterator、HashIterator 才是真正實現(xiàn) 迭代器 的類

final class KeyIterator extends HashIterator
    implements Iterator<K> {
    public final K next() { return nextNode().key; }
}

6.當(dāng)執(zhí)行完 Iterator iterator = HashSet.iterator; 之后,此時的 iterator 對象中已經(jīng)存儲了一個元素節(jié)點

  • 怎么做到的?
  • 回到第 4 步,KeySet().iterator() 方法返回一個 KeyIterator 對象
  • new KeyIterator() 調(diào)用 KeyIterator 的無參構(gòu)造器
  • 在這之前,會先調(diào)用其父類 HashIterator 的無參構(gòu)造器
  • 因此,分析 HashIterator 的無參構(gòu)造器就知道發(fā)生了什么
/**
*         Node<K,V> next;        // next entry to return
*         Node<K,V> current;     // current entry
*         int expectedModCount;  // for fast-fail
*         int index;             // current slot
* HashIterator() {
*             expectedModCount = modCount;
*             Node<K,V>[] t = table;
*             current = next = null;
*             index = 0;
*             if (t != null && size > 0) { // advance to first entry
*                 do {} while (index < t.length && (next = t[index++]) == null);
*             }
*         }
*/
  • next、currentindex 都是 HashIterator 的屬性
  • Node<K,V>[] t = table; 先把 Node 數(shù)組 talbe 賦給 t
  • current = next = null; current、next 都置為 null
  • index = 0; index 置為 0
  • do {} while (index < t.length && (next = t[index++]) == null); 這個 do-while 會在 table 中遍歷 Node 結(jié)點
  • 一旦 (next = t[index++]) == null 不成立 時,就說明找到了一個 table 中的 Node 結(jié)點
  • 將這個節(jié)點賦給 next,并退出當(dāng)前 do-while 循環(huán)
  • 此時 Iterator iterator = HashSet.iterator; 就執(zhí)行完了
  • 當(dāng)前 iterator 的運行類型其實是 HashIterator,而 HashIterator 的 next 中存儲著從 table 中遍歷出來的一個 Node 結(jié)點

7.執(zhí)行 iterator.hasNext

此時的 next 存儲著一個 Node,所以并不為 null,返回 true

public final boolean hasNext() {
    return next != null;
}

8.執(zhí)行 iterator.next()

I.Node<K,V> e = next; 把當(dāng)前存儲著 Node 結(jié)點的 next 賦值給了 e

II.(next = (current = e).next) == null 判斷當(dāng)前結(jié)點的下一個結(jié)點是否為 null

  • (a). 如果當(dāng)前結(jié)點的下一個結(jié)點為 null,就執(zhí)行 do {} while (index < t.length && (next = t[index++]) == null);,在 table 數(shù)組中遍歷,尋找 table 數(shù)組中的下一個 Node 并賦值給 next
  • (b). 如果當(dāng)前結(jié)點的下一個結(jié)點不為 null,就將當(dāng)前結(jié)點的下一個結(jié)點賦值給 next,并且此刻不會去 table 數(shù)組中遍歷下一個 Node 結(jié)點

III.將找到的結(jié)點 e 返回

IV.之后每次執(zhí)行 iterator.next() 都像 (a)、(b) 那樣去判斷遍歷,直到遍歷完成

HashSet 遍歷元素源碼

/**
 * HashSet 源碼分析
 */
public class HashSetSourceMain {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add("java");
        hashSet.add("php");
        hashSet.add("java");
        System.out.println("set = " + hashSet);
        // HashSet 迭代器實現(xiàn)原理
        // HashSet 底層是 HashMap,HashMap 底層是 數(shù)組 + 鏈表 + 紅黑樹
        // HashSet 本身沒有實現(xiàn)迭代器,而是借由 HashMap 來實現(xiàn)的
        // 1. hashSet.iterator() 實際上是去調(diào)用 HashMap 的 keySet().iterator()
        /**
         * public Iterator<E> iterator() {
         *         return map.keySet().iterator();
         *     }
         */
        // 2. KeySet() 方法返回一個 KeySet 對象,而 KeySet 是 HashMap 的一個內(nèi)部類
        /**
         * public Set<K> keySet() {
         *         Set<K> ks = keySet;
         *         if (ks == null) {
         *             ks = new KeySet();
         *             keySet = ks;
         *         }
         *         return ks;
         *     }
         */
        // 3. KeySet().iterator() 方法返回一個 KeyIterator 對象,KeyIterator 是 HashMap的一個內(nèi)部類
        /**
         * public final Iterator<K> iterator()     { return new KeyIterator(); }
         */
        // 4. KeyIterator 繼承了 HashIterator(HashMap的內(nèi)部類) 類,并實現(xiàn)了 Iterator 接口
        // 即 KeyIterator、HashIterator 才是真正實現(xiàn) 迭代器的類
        /**
         * final class KeyIterator extends HashIterator
         *         implements Iterator<K> {
         *         public final K next() { return nextNode().key; }
         *     }
         */
        // 5. 當(dāng)執(zhí)行完 Iterator iterator = hashSet.iterator(); 后
        // 此時的 iterator 對象中已經(jīng)存儲了一個元素節(jié)點
        // 怎么做到的?
        // 回到第 3 步,KeySet().iterator() 方法返回一個 KeyIterator 對象
        // new KeyIterator() 調(diào)用 KeyIterator 的無參構(gòu)造器
        // 在這之前,會先調(diào)用 KeyIterator 父類 HashIterator 的無參構(gòu)造器
        // 因此分析 HashIterator 的無參構(gòu)造器就知道發(fā)生了什么
        /**
         *         Node<K,V> next;        // next entry to return
         *         Node<K,V> current;     // current entry
         *         int expectedModCount;  // for fast-fail
         *         int index;             // current slot
         * HashIterator() {
         *             expectedModCount = modCount;
         *             Node<K,V>[] t = table;
         *             current = next = null;
         *             index = 0;
         *             if (t != null && size > 0) { // advance to first entry
         *                 do {} while (index < t.length && (next = t[index++]) == null);
         *             }
         *         }
         */
        // 5.0 next, current, index 都是 HashIterator 的屬性
        // 5.1 Node<K,V>[] t = table; 先把 Node 數(shù)組 table 賦給 t
        // 5.2 current = next = null; 把 current 和 next 都置為 null
        // 5.3 index = 0; index 置為 0
        // 5.4 do {} while (index < t.length && (next = t[index++]) == null);
        // 這個 do{} while 循環(huán)會在 table 中 遍歷 Node節(jié)點
        // 一旦 (next = t[index++]) == null 不成立時,就說明找到了一個 table 中的節(jié)點
        // 將這個節(jié)點賦給 next,并退出當(dāng)前 do while循環(huán)
        // 此時 Iterator iterator = hashSet.iterator(); 就執(zhí)行完了
        // 當(dāng)前 iterator 的運行類型其實是 HashIterator,而 HashIterator 的 next 中存儲著從 table 中遍歷出來的一個 Node節(jié)點
        // 6. 執(zhí)行 iterator.hasNext()
        /**
         * public final boolean hasNext() {
         *             return next != null;
         *         }
         */
        // 6.1 此時的 next 存儲著一個 Node,所以并不為 null,返回 true
        // 7. 執(zhí)行 iterator.next(),其實是去執(zhí)行 HashIterator 的 nextNode()
        /**
         * final Node<K,V> nextNode() {
         *             Node<K,V>[] t;
         *             Node<K,V> e = next;
         *             if (modCount != expectedModCount)
         *                 throw new ConcurrentModificationException();
         *             if (e == null)
         *                 throw new NoSuchElementException();
         *             if ((next = (current = e).next) == null && (t = table) != null) {
         *                 do {} while (index < t.length && (next = t[index++]) == null);
         *             }
         *             return e;
         *         }
         */
        // 7.1 Node<K,V> e = next; 把當(dāng)前存儲著 Node 節(jié)點的 next 賦值給了 e
        // 7.2 (next = (current = e).next) == null
        // 判斷當(dāng)前節(jié)點的下一個節(jié)點是否為 null
        // a. 如果當(dāng)前節(jié)點的下一個節(jié)點為 null
        // 就執(zhí)行 do {} while (index < t.length && (next = t[index++]) == null);
        // 再 table 數(shù)組中 遍歷,尋找 table 數(shù)組中的下一個 Node 并賦值給 next
        // b. 如果當(dāng)前節(jié)點的下一個節(jié)點不為 null
        // 就將當(dāng)前節(jié)點的下一個節(jié)點賦值給 next,并且此刻不會去 table 數(shù)組中遍歷下一個 Node 節(jié)點
        // 7.3 將找到的節(jié)點 e 返回
        // 7.4 之后每次執(zhí)行 iterator.next(),都像 a、b 那樣去判斷遍歷,直到遍歷完成
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
    }
}

到此這篇關(guān)于Java HashSet添加 遍歷元素源碼分析的文章就介紹到這了,更多相關(guān)HashSet添加 遍歷元素內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java靜態(tài)工廠方法的實例詳解

    Java靜態(tài)工廠方法的實例詳解

    這篇文章主要介紹了 Java靜態(tài)工廠方法的實例詳解的相關(guān)資料,希望通過本文大家能掌握java今天工廠方法,需要的朋友可以參考下
    2017-09-09
  • 關(guān)于解決iReport4.1.1無法正常啟動或者閃退或者JDK8不兼容的問題

    關(guān)于解決iReport4.1.1無法正常啟動或者閃退或者JDK8不兼容的問題

    在安裝使用iReport的過程中遇到一個問題,我的iReport始終不能打開,困擾了我好久。接下來通過本文給大家介紹iReport4.1.1無法正常啟動或者閃退或者JDK8不兼容的問題,需要的朋友可以參考下
    2018-09-09
  • Java數(shù)據(jù)結(jié)構(gòu)之簡單的連接點(link)實現(xiàn)方法示例

    Java數(shù)據(jù)結(jié)構(gòu)之簡單的連接點(link)實現(xiàn)方法示例

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之簡單的連接點(link)實現(xiàn)方法,涉及java指針指向節(jié)點的相關(guān)使用技巧,需要的朋友可以參考下
    2017-10-10
  • Java?中不全部使用?Static?方法的理由

    Java?中不全部使用?Static?方法的理由

    這篇文章主要介紹了Java?中不全部使用?Static?方法的理由,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • 使用Java?Executors創(chuàng)建線程池的9種方法

    使用Java?Executors創(chuàng)建線程池的9種方法

    文章主要介紹了?Java?中Executors類創(chuàng)建線程池的?9?種方法,每種方法都詳細(xì)闡述了實現(xiàn)原理、源代碼分析、參數(shù)解釋、實現(xiàn)過程、特性和使用場景,感興趣的小伙伴跟著小編一起來看看吧
    2024-11-11
  • JAVA面試題之Forward與Redirect的區(qū)別詳解

    JAVA面試題之Forward與Redirect的區(qū)別詳解

    這篇文章主要給大家介紹了在JAVA面試中可能遇到會遇到的一道題,就是java中Forward與Redirect兩者之前的區(qū)別,文中介紹的非常詳細(xì),對大家具有一定參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • SpringBoot快速接入OpenAI大模型的方法(JDK8)

    SpringBoot快速接入OpenAI大模型的方法(JDK8)

    本文介紹了如何使用AI4J快速接入OpenAI大模型,并展示了如何實現(xiàn)流式與非流式的輸出,以及對函數(shù)調(diào)用的使用,AI4J支持JDK8,適用于多種應(yīng)用場景,包括Spring Boot項目,感興趣的朋友一起看看吧
    2025-02-02
  • Java中equals和==的區(qū)別詳解

    Java中equals和==的區(qū)別詳解

    這篇文章主要介紹了詳解 Java 中 equals 和 == 的區(qū)別的相關(guān)資料,equals 和 == 都是用來檢測兩個字符串是否相等,返回值也都是布爾型,但是兩者在內(nèi)部比較的處理中卻不盡相同需要的朋友可以參考下
    2021-09-09
  • JavaSE實現(xiàn)文件壓縮與解壓縮的技巧分享

    JavaSE實現(xiàn)文件壓縮與解壓縮的技巧分享

    我們在日常實際開發(fā)中,對于文件壓縮和解壓縮場景,是非常常見的操作,本文詳細(xì)介紹JavaSE中文件壓縮和解壓縮的實現(xiàn)方法,包括源代碼解析、應(yīng)用場景案例、優(yōu)缺點分析、案例演示、文末總結(jié)等等,請同學(xué)們耐心閱讀
    2024-03-03
  • 深入理解Java設(shè)計模式之解釋器模式

    深入理解Java設(shè)計模式之解釋器模式

    這篇文章主要介紹了JAVA設(shè)計模式之解釋器模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解
    2021-11-11

最新評論

图木舒克市| 台东市| 平乐县| 鹤峰县| 新巴尔虎左旗| 工布江达县| 恩施市| 五河县| 信宜市| 汝州市| 兖州市| 宜丰县| 晋州市| 昌宁县| 忻城县| 上饶县| 万年县| 永靖县| 玉林市| 虹口区| 甘泉县| 年辖:市辖区| 子洲县| 常宁市| 贡山| 齐河县| 临西县| 双牌县| 望都县| 邵武市| 云龙县| 余姚市| 永靖县| 土默特右旗| 康定县| 营口市| 南召县| 贵定县| 昌江| 大宁县| 休宁县|