首页 > 解决方案 > 如何在 Drools 7.59 中测试列表长度?

问题描述

我正在尝试测试对象列表的长度。我正在遵循我在旧版本的 Drools(7.44 及更早版本)中使用的模式,但它似乎不再起作用了。

这是我的规则:

global BookEventResult result;

rule "Person has 3 or more existing checked out books"
when
  BookEvent( type == BookEventType.BORROW )
  Person( $books: checkedOutBooks )
  ArrayList( size >= 3 ) from $books
then
  result.setSuccess(false);
  result.setReason("User has already checked out 3 books");
end

我传递给规则的 Person 实例有 3 项:

class Person {
  List<Book> checkedOutBooks = new ArrayList<>(); // 3 Book instances in here
}

...并且 BookEvent 类型是“借”。我已经通过 IDE 中的调试会话确认了两者。

但是,该规则不会触发。

我正在使用 Drools 7.59.0.Final,特别是drools-engine-classic依赖项(因为我更喜欢 mvel。)还有 Java 17(openjdk)。在 7.50.0.Final 和 7.47.0.Final 中观察到相同的行为;由于 JDK 不兼容,无法测试 45 或 46。47 似乎在 JDK 方面也有点不确定。

我还使用 JDK 11(Eclipse Temurin AdoptOpenJDKHotspot)在 7.59 上重新测试,结果相同。

多年来,我广泛使用了相同的模式。这是第一次让我失望。最新版本的 drools 是否在这里引入了某种形式的非向后兼容性?我现在应该如何检查列表长度?


只是为了咯咯笑,我添加了这两个测试规则来看看发生了什么:

rule "Test - No check"
when
  Person( $books: checkedOutBooks )
then
  System.out.println("Book size: " + $books.size());
  System.out.println( $books.getClass().getName() );
end

rule "Test - Exactly 3 books"
when
  Person( $books: checkedOutBooks )
  ArrayList( size == 3 ) from $books
then
  System.out.println("Three books exactly");
end

第一个测试规则打印Book size: 3java.util.ArrayList。第二个测试规则根本没有触发。

发挥最后的预感,我添加了这个测试规则:

rule "Test - assign to list"
when
  Person( $books: checkedOutBooks )
  $booklist: ArrayList() from $books
then
  System.out.println("booklist size: " + $booklist.size());
end

该规则根本不会触发。我尝试了java.util.Listjava.util.ArrayList

标签: drools

解决方案


我环顾四周,发现了一些“大小”和“列表”的工作用例

rule "Person has 3 or more existing checked out books"
when
  BookEvent( type == BookEventType.BORROW )
  $person: Person( $books: checkedOutBooks, $books.size >= 3 )
  $book1: Book() from $person.checkedOutBooks.get(0)
  $book3: Book(name == 'book3') from $person.checkedOutBooks
  $bookNames: List(size >= 3) from accumulate (Book($name: name) from $books, collectList($name)) 
then
  System.out.println("First book " + $book1);
  System.out.println("Third book " + $book3);
  System.out.println("Book names " + $bookNames);
  System.out.println("Books " + $books);
end

但是我认为您的期望是错误的,因为语句from <collection>旨在遍历集合,并且ArrayList内部没有元素。我还尝试将流口水降级到 7.5.0.Final 并且行为似乎是一致的。


推荐阅读