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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

java集合——视图与包装器

發布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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/ViewAndWrapper.java


1.1)通過使用視圖可以獲得其他的實現了集合接口和映射表接口的對象;

  • 1.1.1)視圖定義:映射表類的keySet方法就是這樣一個荔枝;keySet 方法返回一個實現了Set接口的類對象, 這個類的方法對原映射表進行操作, 這種集合稱為視圖;

1.2)集合框架中的遺留類圖概覽

1.3)輕量級集包裝器

  • 1.3.1)Arrays類的靜態方法asList 將返回一個包裝了普通 java 數組的List 包裝器。 這個方法可以將數組傳遞給一個期望得到列表或集合變元的方法, 例如:
Card[] cardDeck = new Card[25]; List<Card> cardList = Arrays.asList(cardDeck); (數組轉List視圖對象)

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

  • A1)返回的對象不是 ArrayList。 它是一個視圖對象, 帶有訪問底層數組的get和set方法;而改變該數組大小的所有方法(與迭代器相關的add 和 remove方法) 都會拋出一個UnsupportedOperationException 異常;
  • A2)asList方法: 它已經被聲明為一個具有可變參數的方法, 除了可以傳遞一個數組外, 還可以將各個元素直接傳遞給這個方法:
List<String> names = Arrays.asList<"a", "b", "c">;
  • A3)以上這個方法調用 Collections.nCopies(n , anObject) : 將返回一個實現了 List接口的不可修改對象, 并給人一種包含n個元素, 每個元素都是 Object的 錯覺;
  • 1.3.2)看個荔枝:(干貨——創建了 100個 DEFAULT, 由于字符串對象只存儲了一次, 所以付出的存儲代價很小, 這是視圖技術的一種巧妙的應用)

List<String> settings = Collections.nCopies(100, "DEFAULT");

干貨問題:(如何區分 Collection 和 Collections)

  • Anotation) Collections 類包含很多實用方法, 這些方法的參數和返回值都是集合。 不要將 Collection接口 和 Collections 包裝類 混淆起來了;

  • 1.3.3)調用以下代碼: Collections.singleton(anObject); 則返回一個視圖對象。 這個對象實現了Set 接口。 返回的對象實現了一個不可修改的單元素集, 而不需要付出建立數據結構的 開銷。 singletonList 和 singletonMap 方法類似;

    1.4) 子范圍

  • 1.4.1)可以為很多集合建立子范圍視圖;
    如, List g2 = staff.subList(10,20); 從列表staff 中取出 第10個~第19個元素;(第一個 索引包含在內,第二個索引不包含在內)

  • 1.4.2)可以將任何操作應用到子范圍, 并且能夠自動地反應整個列表的情況;
    如, g2.clear(); 現在, 元素自動地從 staff 列表中清除了,并且g2 為空;
  • 1.4.3)對于有序集合映射表, 可以使用 排序順序而不是元素位置建立子范圍。

  • 1.4.3.1)SortedSet 接口說明了3個方法:

SortedSet<E> subSet(E from ,E to) SortedSet<E> headSet(E to) SortedSet<E> tailSet(E from)
  • 以上方法將返回 大于等于from 小于to的所有元素子集;
  • 1.4.3.2)有序映射表有類似方法:
SortedSet<E> subMap(E from ,E to) SortedSet<E> headMap(E to) SortedSet<E> tailMap(E from)
  • 返回映射表視圖, 該映射表包含鍵落在指定范圍內的所有元素;
  • 1.4.4) java SE6 引入的 NavigableSet 接口 賦予子范圍操作更多 的控制能力。 可以指定是否包括邊界:
NabigableSet<E> subSet(E from, boolean fromInclusive, E to, boolean toInclusive); NabigableSet<E> headSet(E to, boolean toInclusive); NabigableSet<E> tailSet(E from, boolean fromInclusive);


1.5)不可修改視圖

  • Collections 還有幾個方法, 用于產生集合的不可修改視圖。 這些視圖對現有集合增加了一個運行時的檢查。 如果發現試圖對集合進行修改, 就拋出一個異常, 同時這個集合將保持未修改狀態;
    (再次提醒:注意區分 Collection 和 Collections)
  • 1.5.1)可以使用下列6種方法獲得不可修改視圖:
Collections.unmodifiableCollection Collections.unmodifiableList Collections.unmodifiableSet Collections.unmodifiableSortedSet Collections.unmodifiableMap Collections.unmodifiableSortedMap
  • 每個方法都定義于一個接口。如, Collections.unmodifiableList 與 ArrayList、LinkedList 或者任何實現了 List接口的其他類一起協同工作;

  • 1.5.1荔枝):

List<String> staff = new LinkedList<>(); lookAt(Collections.unmodifiableList(staff)); // 返回一個不可修改視圖, 傳遞給 loopAt方法;
  • Collections.unmodifiableList 方法返回一個實現List接口的類對象。當然,lookAt方法 可以調用 List 接口中的所有方法, 而不只是訪問器。但是所有的更改器方法,已經被重新定義為 拋出一個 UnsuportedOperationException 異常,而不是 將調用傳遞給底層集合;
  • 1.5.2)不可修改視圖并不是 集合本身不可修改 (干貨——只是無法通過其投影出的視圖修改原始集合)。 仍然可以通過集合的原始引用對集合進行修改。并且仍然可以讓集合的元素調用更改方法;
  • 1.5.3)由于視圖只是包裝了 接口而不是 實際的集合對象, 所以只能訪問 接口中定義的方法; 如, LinkedList 類有一些非常方便的方法, addFirst 和 addLast , 它們都不是 List接口的方法,不能通過修改視圖進行訪問;

Warning)

  • W1) unmodifiableCollection 方法將返回一個集合, 它的equals 方法不調用底層集合的equals 方法; 相反,它繼承了 Object 類的 equals 方法, 該方法只是檢測兩個對象是否是同一個對象;
  • W2)如果將 集 或 列表轉換成集合, 就再也無法檢測其內容是否相同了, 視圖就是以這種方式運行的, 因為內容是否相等的檢測在分層結構的這一層上沒有定義妥當;
  • W3)視圖將以同樣的方式處理 hashCode 方法;

1.6)同步視圖

  • 1.6.1)如果由多個線程訪問集合,就必須確保集不會被意外破壞, 類庫的設計者使用視圖及直接來確保常規集合的線程安全。
  • 1.6.2)例如, Collections 類的 靜態 synchronizedMap 方法將任何一個映射表轉換成具有同步訪問方法的 Map:
Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>());

1.7)檢查視圖

  • 1.7.1)出現的問題:
ArrayList<String> strings = new ArrayList<>(); ArrayList rawList = strings; rawList.add(new Date());//
  • 這個錯誤的 add 命令在運行時檢測不到。 相反,只有在 調用 get方法, 并將其 轉換為 String 時,這個類才會拋出一個異常;

  • 1.7.2)解決方法:檢查視圖可以探測到這類問題。下面定義了一個安全列表:
    List safeString = Collections.checkedList(strings, String.class);
    視圖的add 方法將檢測 插入的對象是否屬于給定的類。 如果不屬于給定的類, 就立即拋出一個 ClassCastException。 這樣做的好處是錯誤可以在正確的位置得以報告:

ArrayList rawList = safeString; rawList.add(new Date()); // checked list chrows a ClassCastException


Warning)

  • W1)被檢測視圖受限于 虛擬機可以運行的運行時檢查。例如, 對于ArrayList

總結

以上是生活随笔為你收集整理的java集合——视图与包装器的全部內容,希望文章能夠幫你解決所遇到的問題。

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