2014-02-23 40 views
3

我正在嘗試使用Guava Cache作爲ConcurrentLinkedHashMap的替代品。然而我發現雖然ConcurrentLinkedHashMap允許我按照插入的順序遍歷地圖,但Guava的asMap()方法不會以任何特定的順序返回元素。我是否錯過了一些東西,或者這個功能根本不可用?是否可以按照插入/訪問的順序遍歷番石榴緩存?

實例(要打印的鍵,值和項):

Cache<Integer, Integer> cache = CacheBuilder.newBuilder().maximumSize(10).initialCapacity(10) 
      .expireAfterAccess(10000, TimeUnit.SECONDS).build(); 

    cache.put(1, 1); 
    cache.put(2, 2); 
    cache.put(3, 3); 
    cache.put(4, 4); 
    cache.put(5, 5); 
    cache.put(6, 6); 

    Iterator<Integer> iter1 = cache.asMap().keySet().iterator(); 

    System.out.println("Keys"); 
    while (iter1.hasNext()) 
     System.out.println(iter1.next()); 

    System.out.println("Values"); 
    Iterator<Integer> iter2 = cache.asMap().values().iterator(); 

    while (iter2.hasNext()) 
     System.out.println(iter2.next()); 

    System.out.println("Entries"); 
    Iterator<Entry<Integer, Integer>> iter3 = cache.asMap().entrySet().iterator(); 

    while (iter3.hasNext()) 
    { 
     Entry<Integer,Integer> entry = iter3.next(); 
     System.out.println(entry.getKey() + " " + entry.getValue()); 
    } 

打印:

Keys 
2 
6 
1 
4 
3 
5 
Values 
2 
6 
1 
4 
3 
5 
Entries 
2 2 
6 6 
1 1 
4 4 
3 3 
5 5 
+0

這個問題問得好,它看起來像答案是「否」......你可以實現你自己的'Cache',但不能在'CacheBuilder'中使用它...... – fge

+0

實現我自己的Cache意味着複製Guava Cache已經保留的排序信息。這看起來很尷尬。 – Malt

+0

'Cache'是一個接口。而Guava的緩存AFAICS不保證訂購信息。我的意思是你可以實現'Cache',以便底層映射是'ConcurrentLinkedHashMap';現在它是'ConcurrentHashMap'的衍生物。但是,即使你這樣做了,我也不知道如何在'CacheBuilder'中使用它,所以... – fge

回答

1

(回答我的問題)

看來FGE的答案是正確的,並且Guava Cache不能按照插入順序迭代。作爲一種解決方法,我使用了先前提到的ConcurrentLinkedHashMap,它功能較少,但允許有序迭代。

我還是感激的正式答覆從別人的番石榴隊,因爲這似乎表明ConcurrentLinkedHashMap沒有完全融入番石榴(違背ConcurrentLinkedHashMap文檔)

+3

正式答案:我們沒有將此功能添加到番石榴的計劃 - 對不起! –

+0

好吧,夠公平的。謝謝! – Malt

+0

現在可通過Java 8重寫[Caffeine](https://github.com/ben-manes/caffeine),通過[policy api](https://github.com/ben-manes/caffeine) /維基/政策)。 –