2

流口水的禁忌之一包括在结果(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);
}

使用流口水方言如何做类似的事情?

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

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

如果这是解决问题的最佳方法,我担心我将不得不添加大量事实。我已经有几千了。这将创造数以万计的更多。我不担心记忆。相反,我担心遍历所有这些集合并将它们的元素添加到工作内存中所需的时间。任何人都可以评论这是否是最好的方法,或者是否存在更好的方法?

4

1 回答 1

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> {}
于 2014-03-21T08:36:25.257 回答