2015-06-16 25 views
0

我必須使用Guava's LoadingCache用於緩存xpath值,其值爲key => xpath expression,值爲xpath values如何不向Guava的LoadingCache添加空值?

但麻煩是,並非所有的xpthes都有值。很多xpath值都有空值(如果要清晰的話,則爲null)。

下面是代碼片段:

private LoadingCache<String, List<String>> cachedXpaths = CacheBuilder.newBuilder() 
     .expireAfterWrite(3, TimeUnit.MINUTES) 
     .maximumSize(1000) 
     .concurrencyLevel(5) 
     .weakKeys() 
     .build(new CacheLoader<String, List<String>>() { 
      @Override 
      public List<String> load(String key) throws Exception { 
       return createListByKey(key); 
      } 
     }); 

private static List<String> createListByKey(String key) throws Exception { 
    List<String> values = null; 
    try { 
     values = instance.getXpathValues(key); 
    } catch (XPathExpressionException ignore) { 
    } 
    return values; 
} 

結果我:

testEncounterSection(com.epam.cdatest.section.EncountersSectionTest) Time elapsed: 0.002 sec <<< FAILURE! 
com.google.common.util.concurrent.UncheckedExecutionException: com.epam.cdatest.exceptions.XpathHasEmptyValueException 
    at com.epam.cdatest.parsers.XpathEvaluator.getXpathValues(XpathEvaluator.java:123) 
    at com.epam.cdatest.parsers.XpathEvaluator.createListByKey(XpathEvaluator.java:53) 
    at com.epam.cdatest.parsers.XpathEvaluator.access$000(XpathEvaluator.java:32) 
    at com.epam.cdatest.parsers.XpathEvaluator$1.load(XpathEvaluator.java:46) 
    at com.epam.cdatest.parsers.XpathEvaluator$1.load(XpathEvaluator.java:43) 

如何避免這種情況,調用load()當EPATH是空的?

+2

爲什麼你想避免通話到'加載()'而不是僅僅返回一個空列表?事實上,緩存無法知道哪些密鑰不被允許,因此會嘗試加載至少一次。裝載程序然後必須決定如何處理密鑰。 – Thomas

+0

@Thomas如何跳過這個空列表返回?或者如何調優緩存來首先刪除空列表? –

+0

它不會跳過'return values'調用,但在此之後緩存不會再加載該給定密鑰的值,並且將始終返回該空白列表,這表明該密鑰沒有xpath值。 – Thomas

回答

3

如果你想要一個空List<String>和一個空的一個區分,因爲LoadingCache不支持空值,你可以使用一個LoadingCache<String, Optional<List<String>>>

private LoadingCache<String, Optional<List<String>>> cachedXpaths = CacheBuilder.newBuilder() 
     .expireAfterWrite(3, TimeUnit.MINUTES) 
     .maximumSize(1000) 
     .concurrencyLevel(5) 
     .weakKeys() 
     .build(new CacheLoader<String, Optional<List<String>>>() { 
      @Override 
      public Optional<List<String>> load(String key) { 
       try { 
        // If getXpathValues() can also return null, use fromNullable() 
        return Optional.of(instance.getXpathValues(key)); 
       } catch (XPathExpressionException | XpathHasEmptyValueException ignore) { 
        // Maybe log something here as well 
        return Optional.absent(); 
       } 
      } 
     }); 

更新:如果你是不熟悉OptionalJavadocWiki中的頁面,以及Java 8的所有文檔,它們現在包含一個等效的類。

TL; DR是可以對其內容的存在進行測試的包裝:

Optional<List<String>> optionalXpaths = cachedXpaths.getUnchecked(str); 
if (optionalXpaths.isPresent()) { 
    List<String> xpaths = optionalXpaths.get(); 
    // Do something with xpaths 
} 

或可選擇地(但它的醜陋):

List<String> xpaths = cachedXpaths.getUnchecked(str).orNull(); 
if (xpaths != null) { 
    // Do something with xpaths 
} 
+0

這種情況下'Optional.absent()'會返回什麼? –

+0

查看我的更新回答。 –

相關問題