日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java集合——映射表+专用集合映射表类

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java集合——映射表+专用集合映射表类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【0】README

0.1) 本文描述轉自 core java volume 1, 源代碼為原創,旨在理解 java集合——映射表+專用集合映射表類 的相關知識;
0.2) for full source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/MapTest.java + https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/MapTestOne.java + https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/EnumSetAndEnumMapTest.java


【1】 映射表(鍵值對——HashMap + TreeMap)

1.1)映射表: 通常,我們知道某些鍵的信息, 想要查找與之對應的元素, 映射表就是為此目的而設計的;(鍵值對)

  • 1.1.1)java類為映射表提供了兩個通用的實現: HashMap 和 TreeMap, 它們都實現了 Map 接口;
  • 1.1.2)散列映射表對鍵進行散列, 樹映射表用鍵的整體順序對元素進行排序,并將其組織成搜索樹;
  • 1.1.3)散列或 比較函數只能作用于鍵。 與鍵關聯的值不能進行散列或比較;(只與key有關, 與value 無關);

1.2)應該選擇 散列映射還是樹映射表呢? 如果不需要按照排列順序訪問鍵, 就最好選擇散列;(TreeMap 有序, 而HashMap無序)

  • 1.2.1)看個荔枝:
Map<String, Employee> staff = new HashMap<>(); // HashMap implements Map Employee harry = new Employee(); staff.puf("hehe", harry);

對以上代碼的分析(Analysis):

  • A1)要檢索一個對象,提供一個鍵:
String s = "hehe"; e = staff.get(s) ; //gets harry
  • 如果在 映射表中沒有與給定鍵對應的信息, get 將返回 null;
  • A2) remove方法用于從映射表中刪除給定鍵的對應元素, 而 size 用戶返回映射表的元素數目;

1.3)獲得映射表的視圖 (干貨)

  • 1.3.1)映射表有3個視圖:鍵集、值集 和 鍵值對集。鍵集和鍵值集對形成了一個集合,因為在映射表中一個鍵只能有一個副本。
  • 1.3.2)下面方法將返回 3個 視圖:
Set<K> keySet(); Collection<K> values(); Set<Map.Entry<K,V>> entrySet

Attention)

  • A1) keySet 既不是 HashSet 也不是 TreeSet, 而是實現了 Set 接口的某個其他類的對象;
  • A2) Set接口擴展了 Collection接口, 因此,可以與使用任何集合一樣使用 keySet;

  • 1.3.3)看個荔枝:

Set<String> keys = map.keySet(); for(String key : keys) {do sth with key }

Hint)

  • H1)如果想要查看鍵和值, 就可以通過枚舉 各個條目查看,以避免對值進行查找。可以使用下面的代碼框架:
for(Map.Entry<String , Employee> entry: staff.entrySet()) {String key = entry.getKey();Employee e = entry.getValue();do sth with key }
  • H2)如果調用迭代器的 remvoe方法, 實際上就從映射表中刪除了 鍵以及對應的值。 但是, 不能將元素添加到 鍵集的視圖中KeySet;如果試圖調用add 方法, 將會拋出一個 UnsupportedOperationException異常;

1.4)看個荔枝:

API java.util.Map<K, V> 1.2 V get(OBject key) V put(K key, V value) void putAll(Map<? extends K, ? extends V> entries) boolean containsKey(Object key) boolean containsValue(Object value) Set<Map.Entry<K,v> entrySet> Set<K> keySet() Collection><V> values();API java.util.Map.Entry<K, V> 1.2 K getKey() V getValue() V setValue(V newValue)API java.util.HashMap<K, V> 1.2 HashMap() HashMap(int initialCapacity) HashMap(int initialCapacity, flaot loadFactor)API java.util.TreeMap<K, V> 1.2 TreeMap(Comparator<? super K> c) TreeMap(Map<? super K, ? extends V> entries) TreeMap(SortedMap<? extends K, ? extends V> entries)API java.util.SortedMap<K, V> 1.2 Comparator<? super K> comparator() K firstKey() K lastKey()

【2】專用集合映射表類

2.1)弱散列映射表(WeakHashMap)

  • 2.1.1)出現的問題: 設計 WeakHashMap 類是為了解決一個有趣的問題。 如果有一個值, 對應的鍵已經不再使用了,將會出現什么情況呢?假定對某個鍵的最后一次引用已經消亡, 不再有任何途徑引用這個值的對象了。 但是,由于在程序中的任何部分沒有再出現這個鍵, 所以,這個鍵值對無法從映射表中刪除。 為什么垃圾回收器不能刪除它呢? 難道刪除無用的對象不是垃圾回收器的工作嗎?
  • 2.1.2)垃圾回收器: 它跟蹤活動的對象, 只要映射表對象是活動的, 其中的所有桶都是活動的, 它們不能被回收。
  • 2.1.3)因此,需要由程序負責從長期存活的映射表中刪除那些無用的值。或者使用 WeakHashMap 完成這件事情。
  • 2.1.4)當對鍵的唯一引用來自散列條目時, 這一數據結構與垃圾回收器協同工作一起刪除鍵值對;

2.2)了解 WeakHashMap的內部運行情況: WeakHashMap 使用 弱引用(weak reference)保存鍵。

  • WeakReference對象將引用保存到另外一個對象中, 在這里,就是散列表鍵。對于這種類型的對象,垃圾回收器用一種特有的方式進行處理。 通常,如果垃圾回收器發現這個特定的對象已經沒有他人引用了,就將其回收。然而, 如果某個對象只能由 WeakReference 引用, 垃圾回收器仍然會回收它, 但要將引用這個對象的弱引用放入隊列中。 WeakHashMap 將周期性地檢查隊列, 以便找出新添加的弱引用。 一個弱引用進入隊列意味著這個鍵不再被他人使用, 并且已經被收集起來。于是 , WeakHashMap 將刪除對應的條目;

2.3)鏈接散列集和鏈接映射表(LinkedHashSet 和 LinkedHashMap)

  • 2.3.1)Java SE 1.4 增加了兩個類: LinkedHashSet 和 LinkedHashMap, 用來記住插入元素項的順序(干貨——引入鏈接散列集和鏈接散列表的原因, LinkedHashSet 和 LinkedHashMap, 用來記住插入元素項的順序), 這樣就可以避免在散列表中的項從表面上看是隨機排列的。當條目插入到表中時,就會并入到雙向鏈表中;
  • 2.3.2)看個荔枝:
Map<String, Employee> staff = new HashMap<>();staff.put("14", new Employee("Amy"));staff.put("56", new Employee("Harry"));staff.put("15", new Employee("Gary"));staff.put("45", new Employee("Francesca"));
  • 然后 staff.keySet().iterator() 以下面次序枚舉鍵:
    (https://github.com/pacosonTang/core-java-volume/blob/master/chapter13/MapTestOne.java)
    并且 staff.values().iterator() 以下列順序枚舉這些值;

  • 2.3.3)鏈接散列映射表將用訪問順序,而不是插入順序, 對映射表條目進行迭代。每次調用 get 或 put, 受到影響的條目將從當前位置刪除, 并放到條目鏈表的尾部;

  • 2.3.4)訪問順序對于實現高速緩存的 “最近最少使用”原則十分重要。
  • 2.3.5)可以構造一個 LinkedHashMap的子類, 然后覆蓋下面這個方法:
protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
  • 2.3.6)看個荔枝:(每當方法返回true時, 就添加一個新條目, 從而導致刪除 eldest 條目), 下面的高速緩存可以存放100個元素:
Map<K, V> cache = new LinkedhashMap<>(128, 0.75F, true) {protecte boolean removeEldestEntry(Map.Entry<K, V> eldest){return size() > 100;} }

2.4)枚舉集與映射表

  • 2.4.1) EnumSet 是一個枚舉類型元素集的高效實現。 如果對應的值在集合中, 相應的位被置為1;
  • 2.4.2) EnumSet 類沒有公共的構造器。 可以使用靜態工廠方法構造這個集;
enum Weekday {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, , SATURDAY, SUNDAY} EnumSet<Weekday> always = EnumSet.allOf(Weekday.class); EnumSet<Weekday> never = EnumSet.noneof(Weekday.class); EnumSet<Weekday> workday= EnumSet.range(Weekday.MONDAY, Weekday.FRIDAY); EnumSet<Weekday> mwf = EnumSet.of(Weekday.MONDAY, Weekday.WEDNESDAY, Weekday.FRIDAY);

  • 2.4.3)可以修改 Set接口的常用方法來修改 EnumSet;
  • 2.4.4)EnumMap 是一個鍵類型為 枚舉類型的映射表。 它可以直接且高效地用一個值數組實現, 在使用時, 需要再構造器中指定鍵類型:
EnumMap<Weekday, Employee> map = new EnumMap<>(Weekday.class);

Annotation) 在 EnumSet的 API文檔中, 將會看到 E extends Enum , 簡單的說, 它的意思是 E 是一個枚舉類型。 所有的枚舉類型都擴展于 泛型 Enum 類;如 Weekday 擴展于 Enum;

API java.util.EnumSet<E extends Enum<E>> 5.0static <E extends Enum<E>> EnumSet<E> allOf(Class<E> enumType) 返回一個包含給定枚舉類型的所有值的集合;static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> enumType) 返回一個空集, 并有足夠的空間保存給定的枚舉類型所有的值;static <E extends Enum<E>> EnumSet<E> range(E from , E to) 返回一個包含 from~to 之間的所有值(包括邊界fromto)的集;static <E extends Enum<E>> EnumSet<E> of(E value) static <E extends Enum<E>> EnumSet<E> of(E value, E ...values) 返回包括給定值的集合;API java.util.EnumMap<K extends Enum<K, V>> 5.0 EnumMap<Class<K> keyType> 構造一個鍵為給定類型的 空映射集;java.util.IdentityHashMap<K, V> 1.4 IdentityHashMap() IdentityHashMap(int expectedMaxSize) 構造一個空的標識散列映射集,其容量大于1.5 * expectedMaxSize的2 的最小次冪( expectedMaxSize 的默認值為21)API java.lang.System 1.0static int idnetityHashCode(Object obj) 1.1 返回 Object.hashCode 計算出來的相同散列碼, 即使 obj 所屬的類已經重新定義了了 hashCode 方法也是如此;

總結

以上是生活随笔為你收集整理的java集合——映射表+专用集合映射表类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。