为地图中的每个元素drools mvel

时间:2014-03-20 23:35:17

标签: java map foreach drools mvel

drools中的一个no-nos包括手动迭代结果中的集合(then子句)。我需要编写一个流氓,它有效地迭代地图,同时为该地图中的每个键值对做一些事情。换句话说,我需要在drools中复制for-each循环的行为,而不实际编写for-each循环。

现在,我意识到我可以在结果中写一个for-each循环。我想让我的代码尽可能接近drools标准。我在下面列出了一个更具体的例子。

我有一个字符串和颜色的地图。

Map<String, Color> colorMap

对于地图中的每种颜色,我想检查一个不同的集合,以找到该颜色的确切代码。

Map<Color, ColorCode> colorCodes

Java方言方法类似于以下内容:

for (Map.Entry<String, Color> entry : colorMap.entrySet())
{
    ColorCode code = colorCodes.get(entry.getValue());

    thenconsequence.do(code);
}

使用drools方言会如何做类似的事情?

更新 我越想到这个问题,我就越关注我不应该在drools的上下文中进行这种地图查找/迭代。正确的做法可能是将这些集合的事实对象表示插入到工作内存中。例如,我可能将每种颜色包裹在一个colorFact中,该colorFact包含Color,一个字段指示颜色名称。与代码相同。然后,我可以按照以下方式写下一个流口水:

when
Color(name=="blue", $c:color)
ColorCode(name == "blue", $code:colorCode)
then 
  $code.printCode();
end

如果这是最好的方式,我会关注我必须添加的大量事实。我已经有成千上万。这将创造数万个。我不担心记忆。相反,我担心迭代所有这些集合并将其元素添加到工作内存所需的时间。任何人都可以评论这是否是最好的方法,或者是否存在更好的方法?

1 个答案:

答案 0 :(得分:0)

虽然这可以使用一组简单的Java语句来完成,但是这里有一个如何在单个规则中完成的事情,但是插入的开销最小(我认为)很多:

rule "matchcolorcode"
when
    $cm: ColorMap()
    Map.Entry( $key: key, $color: value ) from $cm.entrySet()
    $ccm: ColorCodeMap( $ccm.containsKey($key) )
then
    System.out.println( $key + ": " + $color + ", " + $ccm.get($key) );
end

事实是HashMap的泛型实例化的简单包装器,例如:

class ColorMap extends HashMap<String,Color> {}