2012-05-02 238 views
2

我有一個Predicates的集合,說List<Predicate<File>>。然後我有一個File,我需要獲取與該文件匹配的謂詞(如果有的話)。我正在考慮沿着使用Iterables.find()的方向,但當然這需要Predicate沒有值傳入Predicate。我想過實施以下內容,但不知道是否已經存在一種機制。查找匹配的謂詞。謂詞的謂詞?

public static <T> Predicate<Predicate<? super T>> createInversePredicate(
     final T value) { 
    return new Predicate<Predicate<? super T>>() { 

     @Override 
     public boolean apply(Predicate<? super T> input) { 
      return input.apply(value); 
     } 
    }; 
} 

這將使我做到以下幾點:

private List<Predicate<File>> filters = ...; 

@Nullable 
Predicate<File> findMatching(File file){ 
    return Iterables.find(filters, createInversePredicate(file), null); 
} 

有沒有更好的辦法?

回答

3

番石榴團隊成員在這裏。

這就是我該怎麼做的。沒有更好的方法。

+0

使用Optional<Predicate<File>>代替@Nullable它已經有像「createInversePredicate」實用方法?如果不是,我應該將其作爲一個問題提出建議嗎? –

+0

你可以,但它似乎不是一個非常常見的用例。 –

3

我將避免創造一個「逆」謂詞的複雜性,簡單地使用命令式代碼:

private List<Predicate<File>> filters = ...; 

@Nullable 
Predicate<File> findMatchingFilter(File file){ 
    for (Predicate<File> filter : filters) { 
     if (filter.apply(file)) { 
      return filter; 
     } 
    } 
    return null; 
} 

它更簡單,接下來的程序員不需要花1分鐘時間來了解這個「逆」上游業務:)

+0

我不同意有兩個原因:1)我討厭重複的代碼,這包括重做庫中存在的內容。這是一個錯誤可以滑入的區域。2)Guava中有很多方法可以在不添加代碼的情況下使用它(過濾器,查找,findOnly等) –

+0

我不是說這樣的逆謂詞總是一個壞主意(這就是爲什麼我昨天提出了你的問題)。如果您發現自己多次和/或以不同方式重複使用這樣的謂詞(過濾,查找,findOnly等),這是有道理的。但是,在那之前,我會遵循YAGNI原則,並努力簡化。 Guava wiki中的功能性成語警告部分也是相關的:http://code.google.com/p/guava-libraries/wiki/FunctionalExplained –

+1

請注意,感謝您的評論。 –

0

的Java 8的用戶可以這樣做:

Predicate<File> findMatching(File file) { 
    List<Predicate<File>> matchingFilters = filters.stream().filter(predicate -> predicate.test(file)).collect(Collectors.toList()); 
    return matchingFilters.isEmpty()? null : matchingFilters.get(0); 
} 

在這裏,我假設只有一個謂語匹配的文件。

您也可以在Java 8