问题
I am trying to collect some objects in Drools, but I want to only collect objects which have the same attribute. To wit, imagine a TestData class:
public class TestData {
int number;
String name;
//Getters, setters, rest of class
}
I want to use collect to get all TestDatas which have the same name. For the following data set, I want a rule which can collect the first two (both having the name 'Test1') and the second two ('Test2') as separate collections.
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' >
Something like
rule "Test Rule"
when
$matchingTestDatas : ArrayList( size > 1 ) from collect ( TestData( *magic* ) )
then
//Code
end
But obviously that won't work without the magic- it gets me an array of all the TestData entries with every name. I can use that as the basis for a rule, and do extended processing in the right hand side iterating over all the test data entries, but it feels like there should be something in drools which is smart enough to match this way.
回答1:
Presumably the "magic" is just:
TestData( name == 'Test1' )
or
TestData( name == 'Test2' )
... for each of the collections. But that seems too obvious. Am I missing something?
Based on the clarification from the OP in the comments on this answer, it would appear that a Map
of collections is required, keyed from the name. To support this, accumulate
is required, rather than collect
.
$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 )
);
来源:https://stackoverflow.com/questions/23505531/using-collect-in-drools-to-get-similar-objects