Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用java streams按谓词筛选时记录筛选结果_Java_Logging_Filter_Java 8_Java Stream - Fatal编程技术网

使用java streams按谓词筛选时记录筛选结果

使用java streams按谓词筛选时记录筛选结果,java,logging,filter,java-8,java-stream,Java,Logging,Filter,Java 8,Java Stream,场景是我创建了不同类型的过滤器,它们根据对象的属性过滤一些对象的列表 为此,我创建了一个AbstractObjectFilter类,每个过滤器都继承了它。 AbstractObjectFilter.java public abstract class AbstractEventFilter { protected abstract Predicate<IEvent> isEligible(); public List<IEvent> getFiltere

场景是我创建了不同类型的过滤器,它们根据对象的属性过滤一些对象的列表

为此,我创建了一个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());
    }
}
公共抽象类AbstractEventFilter
{
受保护的抽象谓词isEligible();
公共列表getFilteredEvents(最终列表事件)
{
return events.stream().filter(isEligible()).collect(Collectors.toList());
}
}
因此,现在每个筛选器都扩展了这个类并重写了isEligible(),在该函数中,它根据其属性返回谓词

例如: MinnumOfPrizeFilter.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;
    }
}
公共类MinimumNumoPrizesFilter扩展了AbstractEventFilter
{
私人int最低奖金;
public minimumnumprizesfilter(@NonNull int minimumnumoffires)
{
this.minimumnumoffires=minimumnumoffires;
}
@凌驾
受保护谓词是可忽略的()
{
return event->event.getPrizeCount();
}
}
类似地,我还创建了许多其他过滤器。有一个applyFilter函数,它迭代筛选对象列表,并通过调用getFilteredEvents函数继续应用筛选


现在,我如何记录每个事件的命运,例如-“x1事件由MinnumOfPrizeFilter筛选器筛选。x1的奖品计数为-10,所需的最低奖品计数为-20”

您只需将括号添加到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
实现。

也许不是最漂亮的解决方案,但它可以工作,您只需更改抽象基类:

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());
    }
}
抽象类AbstractEventFilter{
私有最终记录器Logger=Logger.getLogger(getClass().getCanonicalName());
私有最终字符串filterName=getClass().getSimpleName();
受保护的抽象谓词isEligible();
私有谓词internalIsEligible(){
返回iEvent->{
布尔res=isEligible().test(iEvent);
如果(!res){
logger.info(“事件”+iEvent.toString()+”由“+filterName”过滤);
}
返回res;
};
}
公共列表getFilteredEvents(最终列表事件){
return events.stream().filter(internalIsEligible()).collect(Collectors.toList());
}
}

您可以像以前一样让派生类实现
isELigible()
,只有在
getFilteredEvents
方法中,您才调用
internaliseligible
方法。

这样,您就可以记录过滤的和未过滤的values@P.J.Meisch我知道。peek操作不适合这里,只是在信息上添加了它,因为它对使用java-streams进行日志记录有很多帮助。您需要在每个派生类中实现它class@P.J.Meisch假设谓词在任何实现中都可能不同,并且OP希望打印这些信息(即MinimumNumof),这是必需的。如何打印最小NumOfPrives?向上投票只记录那些被过滤掉的。这里的lambda表达式有什么意义?与只让
AbstractEventFilter
直接实现
谓词
的传统方法相比,子类只需实现
test
方法,这不是一种简化,用
@NonNull
注释
int
变量是毫无意义的,因为
int
值无论如何都不能是
null