首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按日期选择直接前置任务

按日期选择直接前置任务
EN

Stack Overflow用户
提问于 2019-04-09 17:36:08
回答 1查看 27关注 0票数 0

我是Drools的新手,我正在使用Drools 7.12.0来尝试和验证一组仪表读数,它们看起来像

代码语言:javascript
复制
public class MeterReading() {
    private long id;
    private LocalDate readDate;
    private int value;
    private String meterId
    private boolean valid;

/* Getters & Setters omitted */

}

作为验证的一部分,我需要通过readDate将每个MeterReading的值与其直接前身进行比较。

我第一次尝试使用'accumulate‘

代码语言:javascript
复制
when $mr: MeterReading()
  $previousDate: LocalDate() from accumulate(MeterReading($pdate: readDate < $mr.readDate ), max($pdate))

then
  System.out.println($mr.getId() + ":" + $previousDate);
end 

但随后发现这只返回前一个仪表读取的日期,而不是包含它的对象。然后我尝试了一个自定义的累积

代码语言:javascript
复制
when
$mr: MeterReading()

$previous: MeterReading() from accumulate(
      $p: MeterReading(id != $mr.id),
      init( MeterReading prev = null; ),

      action( if( prev == null ||  $p.readDate < prev.readDate) {
         prev = $p;
      }),
      result(prev))
 then
  System.out.println($mr.getId() + ":" + $previous.getId() + ":" + $previous.getReadDate());

 end

但这会选择仪表读数集中最早的读数,而不是直接的前一个读数。谁能给我指出正确的方向,我应该做什么或阅读,以便能够选择每个单独的仪表读取的直接前身。

问候

EN

回答 1

Stack Overflow用户

发布于 2019-04-09 22:31:43

经过进一步的研究,我找到了这篇文章的http://planet.jboss.org/post/how_to_implement_accumulate_functions,我用它来编写我自己的累加函数;\

代码语言:javascript
复制
public class PreviousReadFinder  implements AccumulateFunction {
@Override

public Serializable createContext() {
  return new PreviousReadFinderContext();
}

@Override
public void init(Serializable context) throws Exception {
  PreviousReadFinderContext prfc = (PreviousReadFinderContext) context;
  prfc.list.clear();
}

@Override
public void accumulate(Serializable context, Object value) {
  PreviousReadFinderContext prfc = (PreviousReadFinderContext) context;
  prfc.list.add((MeterReading) value);
}

@Override
public void reverse(Serializable context, Object value) throws Exception {
  PreviousReadFinderContext prfc = (PreviousReadFinderContext) context;
  prfc.list.remove((MeterReading) value);
}

@Override
public Object getResult(Serializable context) throws Exception {
  PreviousReadFinderContext prfc = (PreviousReadFinderContext) context;
  return prfc.findLatestReadDate();
}

@Override
public boolean supportsReverse() {
  return true;
}

@Override
public Class<?> getResultType() {
  return MeterReading.class;
}

@Override
public void writeExternal(ObjectOutput out) throws IOException {

}

@Override
public void readExternal(ObjectInput in) throws IOException,  ClassNotFoundException {

}

private static class PreviousReadFinderContext implements Serializable {
    List<MeterReading> list = new ArrayList<>();

public Object findLatestReadDate() {

Optional<MeterReading> optional =  list.stream().max(Comparator.comparing(MeterReading::getReadDate));
if (optional.isPresent()) {
  MeterReading to = optional.get();
  return to;
}
  return  null;
}
 }
}

我的规则是

代码语言:javascript
复制
rule "Opening Read With Previous"

  dialect "mvel"

  when $mr: MeterReading()
       $pmr: MeterReading() from accumulate($p: MeterReading(readDate < $mr.readDate ), previousReading($p))

then
  System.out.println($mr.getId() + ":" + $pmr.getMeterReadDate());
end

我如何编写一条规则来选择集合中没有先前读数的最大的仪表读数?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55589601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档