2017-04-22 35 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? –