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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Google Guava] 2.4-集合扩展工具类

發布時間:2025/3/21 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Google Guava] 2.4-集合扩展工具类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接?譯文鏈接?譯者:沈義揚,校對:丁一

簡介

有時候你需要實現自己的集合擴展。也許你想要在元素被添加到列表時增加特定的行為,或者你想實現一個Iterable,其底層實際上是遍歷數據庫查詢的結果集。Guava為你,也為我們自己提供了若干工具方法,以便讓類似的工作變得更簡單。(畢竟,我們自己也要用這些工具擴展集合框架。)

Forwarding裝飾器

針對所有類型的集合接口,Guava都提供了Forwarding抽象類以簡化裝飾者模式的使用。

Forwarding抽象類定義了一個抽象方法:delegate(),你可以覆蓋這個方法來返回被裝飾對象。所有其他方法都會直接委托給delegate()。例如說:ForwardingList.get(int)實際上執行了delegate().get(int)。

通過創建ForwardingXXX的子類并實現delegate()方法,可以選擇性地覆蓋子類的方法來增加裝飾功能,而不需要自己委托每個方法——譯者注:因為所有方法都默認委托給delegate()返回的對象,你可以只覆蓋需要裝飾的方法。

此外,很多集合方法都對應一個”標準方法[standardxxx]”實現,可以用來恢復被裝飾對象的默認行為,以提供相同的優點。比如在擴展AbstractList或JDK中的其他骨架類時,可以使用類似standardAddAll這樣的方法。

讓我們看看這個例子。假定你想裝飾一個List,讓其記錄所有添加進來的元素。當然,無論元素是用什么方法——add(int, E), add(E), 或addAll(Collection)——添加進來的,我們都希望進行記錄,因此我們需要覆蓋所有這些方法。

01class?AddLoggingList<E>?extends?ForwardingList<E> {
02????final?List<E> delegate;?// backing list
03????@Override?protected?List<E> delegate() {
04????????return?delegate;
05????}
06????@Override?public?void?add(int?index, E elem) {
07????????log(index, elem);
08????????super.add(index, elem);
09????}
10????@Override?public?boolean?add(E elem) {
11????????return?standardAdd(elem);?// 用add(int, E)實現
12????}
13????@Override?public?boolean?addAll(Collection<??extends?E> c) {
14????????return?standardAddAll(c);?// 用add實現
15????}
16}

記住,默認情況下,所有方法都直接轉發到被代理對象,因此覆蓋ForwardingMap.put并不會改變ForwardingMap.putAll的行為。小心覆蓋所有需要改變行為的方法,并且確保裝飾后的集合滿足接口契約。

通常來說,類似于AbstractList的抽象集合骨架類,其大多數方法在Forwarding裝飾器中都有對應的”標準方法”實現。

對提供特定視圖的接口,Forwarding裝飾器也為這些視圖提供了相應的”標準方法”實現。例如,ForwardingMap提供StandardKeySet、StandardValues和StandardEntrySet類,它們在可以的情況下都會把自己的方法委托給被裝飾的Map,把不能委托的聲明為抽象方法。

PeekingIterator

有時候,普通的Iterator接口還不夠。

Iterators提供一個Iterators.peekingIterator(Iterator)方法,來把Iterator包裝為PeekingIterator,這是Iterator的子類,它能讓你事先窺視[peek()]到下一次調用next()返回的元素。

注意:Iterators.peekingIterator返回的PeekingIterator不支持在peek()操作之后調用remove()方法。

舉個例子:復制一個List,并去除連續的重復元素。

01List<E> result = Lists.newArrayList();
02PeekingIterator<E> iter = Iterators.peekingIterator(source.iterator());
03while?(iter.hasNext()) {
04????E current = iter.next();
05????while?(iter.hasNext() && iter.peek().equals(current)) {
06????????//跳過重復的元素
07????????iter.next();
08????}
09????result.add(current);
10}

傳統的實現方式需要記錄上一個元素,并在特定情況下后退,但這很難處理且容易出錯。相較而言,PeekingIterator在理解和使用上就比較直接了。

AbstractIterator

實現你自己的Iterator?AbstractIterator讓生活更輕松。

用一個例子來解釋AbstractIterator最簡單。比方說,我們要包裝一個iterator以跳過空值。

01public?static?Iterator<String> skipNulls(final?Iterator<String> in) {
02????return?new?AbstractIterator<String>() {
03????????protected?String computeNext() {
04????????????while?(in.hasNext()) {
05????????????????String s = in.next();
06????????????????if?(s !=?null) {
07????????????????????return?s;
08????????????????}
09????????????}
10????????????return?endOfData();
11????????}
12????};
13}

你實現了computeNext()方法,來計算下一個值。如果循環結束了也沒有找到下一個值,請返回endOfData()表明已經到達迭代的末尾。

注意:AbstractIterator繼承了UnmodifiableIterator,所以禁止實現remove()方法。如果你需要支持remove()的迭代器,就不應該繼承AbstractIterator。

AbstractSequentialIterator

有一些迭代器用其他方式表示會更簡單。AbstractSequentialIterator?就提供了表示迭代的另一種方式。

1Iterator<Integer> powersOfTwo =?new?AbstractSequentialIterator<Integer>(1) {?// 注意初始值1!
2????protected?Integer computeNext(Integer previous) {
3????????return?(previous ==?1?<<?30) ??null?: previous *?2;
4????}
5};

我們在這兒實現了computeNext(T)方法,它能接受前一個值作為參數。

注意,你必須額外傳入一個初始值,或者傳入null讓迭代立即結束。因為computeNext(T)假定null值意味著迭代的末尾——AbstractSequentialIterator不能用來實現可能返回null的迭代器。

原創文章,轉載請注明:?轉載自并發編程網 – ifeve.com本文鏈接地址:?[Google Guava] 2.4-集合擴展工具類

from:http://ifeve.com/google-guava-collectionhelpersexplained/?

總結

以上是生活随笔為你收集整理的[Google Guava] 2.4-集合扩展工具类的全部內容,希望文章能夠幫你解決所遇到的問題。

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