2

(强制性新手免责声明)

我正在尝试编写一个规则,只要(scala)列表中的对象匹配条件就会触发。这里的问题是该列表实际上是一个 Option(List[TypeA])... (另外,我意识到将列表存储在工作内存中并不是最佳做法,但鉴于这种情况我不能这样做)

我使用的案例类具有以下结构:

TypeA {
    arg1 : Option[List[TypeB]]
}

TypeB {
    value : String
}

我写了一个类似的规则:

when
    $a : TypeA($l : arg1)
    $b : TypeB() from $l.get()
then
    System.out.println($b)

我已经在没有“.get()”的情况下尝试了这个,只是为了得到一个 Some() 类型的对象。

使用“.get()”,我设法返回了 Option 的内容,但它似乎与预期的类型 (List[TypeB]) 不匹配。相反,返回值的类型似乎是 scala.collection.immutable.$colon$colon

关于问题是什么的任何想法?如果有任何适当的方法来处理 Drools 中的选项?

4

2 回答 2

1

由于您正在执行大量 Java 和 Scala 互操作,我建议您让自己非常熟悉 Scala 的javaconverters功能。这个方便的实用程序集合允许您将 Scala 集合转换为 Java 集合,反之亦然。

在您的情况下,我认为您需要从 Java 集合转换为 Scala 集合。尝试以下操作:

import scala.collection.JavaConverters._

val myScalaList = $b.asScala.toList

文档中的示例:

import scala.collection.JavaConverters._

val sl = new scala.collection.mutable.ListBuffer[Int]
val jl : java.util.List[Int] = sl.asJava
val sl2 : scala.collection.mutable.Buffer[Int] = jl.asScala
assert(sl eq sl2)

您遇到的另一个问题是可变和不可变数据结构。Java 中的标准列表结构是可变的,但默认情况下 Scala 会为您提供一个不可变列表,除非您明确指出您想要一个可变列表。因此,在两个世界之间进行天真的转换时,会出现一些阻抗失配。

正如我在之前的文章中提到的,您可以通过为需要推送到 Drools 的实体创建 Java 类来避免许多问题。在基于 Scala 的项目中混合 Java 类和 Scala 类不是问题。

另一种方法是在 Scala 案例类中创建一个函数,该函数使用该asJava方法将 Scala 集合转换为 Java 集合并返回它。每当您需要引用该 scala 集合时,在您的 DRL 文件中调用此方法,以便获得 Java 集合。

理想情况下,如果 JBoss Drools 愿意,他们需要增强他们当前的编译器以更好地处理 Scala 类型,或者制作一个不会破坏 Scala 类型的专用 Drools Scala 编译器。

于 2015-02-10T11:07:38.103 回答
0

The only thing I can think of to try:

when
    $a : TypeA($l : arg)
    $b : TypeB() from (ArrayList)$l.get() // or some other Java *-List
then
    System.out.println($b)

Worth another try:

when
    $a : TypeA($l : arg)
    $b : TypeB() from $l.get()asJava()*-List
then
    System.out.println($b)
于 2015-02-09T17:53:37.940 回答