使用drools中的collect获取类似对象

使用drools中的collect获取类似对象,drools,business-rules,Drools,Business Rules,我试图收集Drools中的一些对象,但我只想收集具有相同属性的对象。也就是说,想象一个TestData类: public class TestData { int number; String name; //Getters, setters, rest of class } 我想使用collect来获取所有同名的testdata。对于下面的数据集,我需要一个规则,可以将前两个(都有名称“Test1”)和后两个(“Test2”)作为单独的集合进行收集 custom.pa

我试图收集Drools中的一些对象,但我只想收集具有相同属性的对象。也就是说,想象一个TestData类:

public class TestData {
    int number;
    String name;
    //Getters, setters, rest of class
}
我想使用collect来获取所有同名的testdata。对于下面的数据集,我需要一个规则,可以将前两个(都有名称“Test1”)和后两个(“Test2”)作为单独的集合进行收集

custom.package.TestData< number: 1, name:'Test1' >
custom.package.TestData< number: 2, name:'Test1' >
custom.package.TestData< number: 3, name:'Test2' >
custom.package.TestData< number: 4, name:'Test2' >
但显然,如果没有魔法,这是行不通的——它会给我一个包含所有TestData条目和每个名称的数组。我可以使用它作为规则的基础,并在右侧对所有测试数据项进行扩展处理,但感觉drools中应该有一些东西足够聪明,可以以这种方式匹配。

大概“魔力”只是:

。。。对于每个集合。但这似乎太明显了。我错过什么了吗

根据OP在对该答案的评论中的澄清,似乎需要收集的
地图
,从名称键入。要支持此功能,需要使用
累积
,而不是
收集

$tests: HashMap()
    from accumulate( $test : TestData( name == $name ),
        init( HashMap tests = new HashMap(); ),
        action(
            if (tests.get($name) == null) tests.put($name, new ArrayList(); 
            tests.get($name).add($test);
        ),
        reverse(
            tests.get($name).remove($test); 
        ),
        result( tests )
    );

如果我事先知道名字的话,那就行了。但我没有。我想要一个规则,它可以抓取具有相同名称的所有测试数据,同时不预先知道名称是什么,这更有意义。在您的示例中,您正在收集一个
ArrayList
,这让我感到困惑。如果您想创建一个集合集合,其中每个集合都由一个名称键入,那么您可能应该使用
HashMap
。但是,您需要使用
acculate
而不是
collect
。这样做了-acculate得到了我想要的,尽管它有点笨重。只有当列表的大小为2或更多时,才有一种简单的方法来激活规则吗?也就是说,如果只有一个TestData具有给定的名称,我不想麻烦处理它。我只想在两个或多个名称相同时进行处理
TestData( name == 'Test1' )
TestData( name == 'Test2' )
$tests: HashMap()
    from accumulate( $test : TestData( name == $name ),
        init( HashMap tests = new HashMap(); ),
        action(
            if (tests.get($name) == null) tests.put($name, new ArrayList(); 
            tests.get($name).add($test);
        ),
        reverse(
            tests.get($name).remove($test); 
        ),
        result( tests )
    );