2017-04-22 60 views
2

該場景是我創建的篩選器的不同類型,它根據對象的屬性篩選一些對象的列表。在使用java流時記錄篩選結果按謂詞篩選

因此,爲此我創建了一個由每個過濾器繼承的AbstractObjectFilter類。
AbstractObjectFilter.java

public abstract class AbstractEventFilter 
{ 
    protected abstract Predicate<IEvent> isEligible(); 

    public List<IEvent> getFilteredEvents(final List<IEvent> events) 
    { 
     return events.stream().filter(isEligible()).collect(Collectors.toList()); 
    } 
} 

所以現在每一個過濾器擴展該類並覆蓋isEligible(),並在該函數返回根據其性質的謂語。

對於如: - MinNumOfPrizesFilter.java

public class MinimumNumOfPrizesFilter extends AbstractEventFilter 
{ 
    private int minimumNumOfPrizes; 

    public MinimumNumOfPrizesFilter(@NonNull int minimumNumOfPrizes) 
    { 
     this.minimumNumOfPrizes = minimumNumOfPrizes; 
    } 

    @Override 
    protected Predicate<IEvent> isEligible() 
    { 
     return event -> event.getPrizeCount() >= minimumNumOfPrizes; 
    } 
} 

同樣也有我創造了許多其他的過濾器。有一個applyFilter函數遍歷過濾器對象列表,並通過調用getFilteredEvents函數繼續應用過濾器。

現在,我怎麼能記錄每個事件例如命運 - 「被MinNumOfPrizesFilter過濾器X1的獎金數過濾X1事件 - 。10,最小獎計數需要 - 20」

+2

這裏的lambda表達式的要點是什麼?與傳統的只讓'AbstractEventFilter'直接實現'Predicate '的方法相比,這樣子類只需要實現'test'方法,這不是簡單的。 – Holger

+2

順便說一下,用@ NonNull註釋一個'int'變量是毫無意義的,因爲無論如何'int'的值永遠不可能是'null'。 – Holger

回答

3

您可以簡單地添加支架安裝到您lambda表達式和驗證前添加日誌記錄聲明:

return event -> { 
    // LOG.info(event.getName() + " was filtered...") or whatever you use for logging. 
    return event.getPrizeCount() >= minimumNumOfPrizes; 
} 

注意,存在一個peek工作,其意在大多用於登錄Java流:

events.stream() 
     .peek(event -> System.out.println("Filtering event" + event.getName())) 
     .filter(isEligible()) 
     .collect(Collectors.toList()); 

但這在這裏沒有幫助,因爲您需要登錄AbstractEventFilter實現。

+0

與此,你正在記錄過濾和未過濾的值 –

+1

@ P.J.Meisch我知道這一點。 peek操作不適合這裏,只是在信息上添加它,因爲它對使用java-streams進行日誌記錄有很多幫助。 –

+0

並且您需要在每個派生類中實現 –

0

也許不是最漂亮的解決方案,但它的工作原理,你只能改變你的抽象基類:

abstract class AbstractEventFilter { 

    private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); 
    private final String filterName = getClass().getSimpleName(); 

    protected abstract Predicate<IEvent> isEligible(); 

    private Predicate<IEvent> internalIsEligible() { 
     return iEvent -> { 
      boolean res = isEligible().test(iEvent); 
      if (!res) { 
       logger.info("event " + iEvent.toString() + " filtered by " + filterName); 
      } 
      return res; 
     }; 
    } 

    public List<IEvent> getFilteredEvents(final List<IEvent> events) { 
     return events.stream().filter(internalIsEligible()).collect(Collectors.toList()); 
    } 
} 

你保持你的派生類像以前一樣實施isELigible(),只有在你的getFilteredEvents方法,調用internalIsEligibable方法代替。

+0

如何打印minimumNumOfPrizes? –